Hi all,
first of all: this list and you rock! I know that there is no multiple
inheritance, but you can use the concept of mixin.
However, I want to inherit my class another and "mixin" methods from
another class.
To be more precise,
I have a class that inherits another one (that comes from a library and
I do not want to change) and I want the methods of ActiveRecord::Base in
my class. Is there a way to do that (without copying and paste the whole
ActiveRecord::Base class and changing it to a module)?
Hi all,
first of all: this list and you rock! I know that there is no multiple
inheritance, but you can use the concept of mixin.
However, I want to inherit my class another and "mixin" methods from
another class.
To be more precise,
I have a class that inherits another one (that comes from a library and
I do not want to change) and I want the methods of ActiveRecord::Base in
my class. Is there a way to do that (without copying and paste the whole
ActiveRecord::Base class and changing it to a module)?
I would use delegation for one class or the other.
That is: define your class as
class Foo < ActiveRecord::Base
..
def initialize @other = Library::Bar.new
end
end
Or vice versa, whichever makes more sense. And if you can't choose, then
delegate to both.
class FooDB < ActiveRecord::Base
.. more stuff
end
class Foo
def initialize(id) @db = FooDB.find(id) @lib = Library::Bar.new
end
end
Then the interface that Foo exposes to the world can pass some calls to @db,
some to @lib, or (the best news) can combine behaviours from both in
whichever way it likes.
···
On Fri, May 11, 2007 at 10:29:01PM +0900, Bernd wrote:
Hi all,
first of all: this list and you rock! I know that there is no multiple
inheritance, but you can use the concept of mixin.
However, I want to inherit my class another and "mixin" methods from
another class.
To be more precise,
I have a class that inherits another one (that comes from a library and
I do not want to change) and I want the methods of ActiveRecord::Base in
my class. Is there a way to do that (without copying and paste the whole
ActiveRecord::Base class and changing it to a module)?
That would actually be a so called Bridge Design Pattern... I like it I think I will use it for Ruby Patterns
Thanks Brian!
···
On 11 May 2007, at 17:14, Brian Candler wrote:
On Fri, May 11, 2007 at 10:29:01PM +0900, Bernd wrote:
Hi all,
first of all: this list and you rock! I know that there is no multiple
inheritance, but you can use the concept of mixin.
However, I want to inherit my class another and "mixin" methods from
another class.
To be more precise,
I have a class that inherits another one (that comes from a library and
I do not want to change) and I want the methods of ActiveRecord::Base in
my class. Is there a way to do that (without copying and paste the whole
ActiveRecord::Base class and changing it to a module)?
I would use delegation for one class or the other.
That is: define your class as
class Foo < ActiveRecord::Base
..
def initialize @other = Library::Bar.new
end
end
Or vice versa, whichever makes more sense. And if you can't choose, then
delegate to both.
class FooDB < ActiveRecord::Base
.. more stuff
end
class Foo
def initialize(id) @db = FooDB.find(id) @lib = Library::Bar.new
end
end
Then the interface that Foo exposes to the world can pass some calls to @db,
some to @lib, or (the best news) can combine behaviours from both in
whichever way it likes.
Hi all,
first of all: this list and you rock! I know that there is no multiple
inheritance, but you can use the concept of mixin.
However, I want to inherit my class another and "mixin" methods from
another class.
To be more precise,
I have a class that inherits another one (that comes from a library and
I do not want to change) and I want the methods of ActiveRecord::Base in
my class. Is there a way to do that (without copying and paste the whole
ActiveRecord::Base class and changing it to a module)?
I would use delegation for one class or the other.
That is: define your class as
class Foo < ActiveRecord::Base
..
def initialize @other = Library::Bar.new
end
end
Or vice versa, whichever makes more sense. And if you can't choose, then
delegate to both.
class FooDB < ActiveRecord::Base
.. more stuff
end
class Foo
def initialize(id) @db = FooDB.find(id) @lib = Library::Bar.new
end
end
Then the interface that Foo exposes to the world can pass some calls to @db,
some to @lib, or (the best news) can combine behaviours from both in
whichever way it likes.
This is the workaround I just had so far, and now I want to get rid of
it.
I have two classes:
class Myclass < ActiveRecord::Base
def self.find(number)
Anotherclass.find(number)
end
class Anotherclass < SAP4Rails::Base
def self.find(number)
do something
end
But this solution to me seems to be so un-ruby!
As SAP4Rails::Base does not have an explicit superclass, I wondered, if
there is some way to inject it dynamically a super class, because I need
some other methods from ActiveRecord in another application
I know that I could just alter the SAP4Rails class, but I want it in the
way, that you just need ActiveRecord, SAP4RAils and my piece of code.
···
On Fri, May 11, 2007 at 10:29:01PM +0900, Bernd wrote:
I think that would be the ruby way, following the principle of least
surprise. Unfortunately, neither Array nor ActiveRecord::Base do have an
"as_module" method
You seem to be doing something very strange in the above code. You are
replacing one of ActiveRecord::Base's most fundamental operations - load
from database by ID - with something which does something completely
different.
Are you also going to overwrite the save and update methods? In which case,
what functionality from ActiveRecord::Base do you actually want to keep?
I am guessing that SAP4Rails is some sort of remote-procedure call wrapper.
That is, an instance of SAP4Rails::Base represents an object on some remote
SAP server. If that's true, I don't see how it makes sense to try to mix
that with another object which represents a row in a local SQL database.
If Myclass represents something which may exist in the local database and/or
in the remote SAP system, then I'd very much go for delegation.
class MyDb < ActiveRecord::Base; end
class MySap < SAP4Rails::Base; end
class Myclass
def self.find(number) @rec = MyDb.find(number) @sap = MySap.find(number)
end
end
Then you are making it explicit that you are talking about two different
things, and you can implement useful operations (such as copy data from one
to the other)
Regards,
Brian.
···
On Sat, May 12, 2007 at 12:30:00AM +0900, Bernd Burnt wrote:
This is the workaround I just had so far, and now I want to get rid of
it.
I have two classes:
class Myclass < ActiveRecord::Base
def self.find(number)
Anotherclass.find(number)
end
class Anotherclass < SAP4Rails::Base
def self.find(number)
do something
end
foo = Foo.find(2) # performs GET /foo/2.xml
foos = Foo.find(:all) # performs GET /foo.xml
But this doesn't re-use *any* of ActiveRecord. Whilst the interface is
similar in some ways, the underlying operations are very different.
ActiveRecord is very much a wrapper around a SQL database. Almost all the
operations you can perform ultimately get translated into calls on the
database connection for SELECT, UPDATE etc.
The other useful bits of ActiveRecord, like validations, are already mixins
in their own right. That is, they come pre-mixed into ActiveRecord::Base,
but you could mix them into your own class independently.
Regards,
Brian.
···
On Sat, May 12, 2007 at 01:19:26AM +0900, Brian Candler wrote:
On Sat, May 12, 2007 at 12:30:00AM +0900, Bernd Burnt wrote:
> This is the workaround I just had so far, and now I want to get rid of
> it.
>
> I have two classes:
> class Myclass < ActiveRecord::Base
> def self.find(number)
> Anotherclass.find(number)
> end
>
> class Anotherclass < SAP4Rails::Base
> def self.find(number)
> do something
> end
>
> But this solution to me seems to be so un-ruby!
You seem to be doing something very strange in the above code. You are
replacing one of ActiveRecord::Base's most fundamental operations - load
from database by ID - with something which does something completely
different.
Are you also going to overwrite the save and update methods? In which case,
what functionality from ActiveRecord::Base do you actually want to keep?
I am guessing that SAP4Rails is some sort of remote-procedure call wrapper.
That is, an instance of SAP4Rails::Base represents an object on some remote
SAP server. If that's true, I don't see how it makes sense to try to mix
that with another object which represents a row in a local SQL database.
If Myclass represents something which may exist in the local database and/or
in the remote SAP system, then I'd very much go for delegation.
class MyDb < ActiveRecord::Base; end
class MySap < SAP4Rails::Base; end
class Myclass
def self.find(number) @rec = MyDb.find(number) @sap = MySap.find(number)
end
end
Then you are making it explicit that you are talking about two different
things, and you can implement useful operations (such as copy data from one
to the other)