Forum: Ruby on Rails helper for models?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B0be4bfef5a22697a0f44f4fe295aaef?d=identicon&s=25 James Whittaker (aftershock)
on 2006-02-21 23:01
Is there such a thing?

I have some duplicate methods in my models, can I place them somewhere
and call them in to my models, thus keeping DRY?
3c61994644f5d19eb104fb36de8f46da?d=identicon&s=25 Tony Collen (Guest)
on 2006-02-21 23:13
(Received via mailing list)
Put them in a superclass?

Tony
3dd4b52a0946bd698b1d1635a46ea3a3?d=identicon&s=25 Francois Beausoleil (Guest)
on 2006-02-21 23:40
(Received via mailing list)
Hello James,

2006/2/21, James Whittaker <jmwhittaker@gmail.com>:
> Is there such a thing?

Put them in a module, and include the module in your models.  The
module should go into lib/, and the file name should reflect Rails
conventions so that the simple include will be all you need.

Hope that helps !
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-02-22 07:01
(Received via mailing list)
On Feb 21, 2006, at 2:01 PM, James Whittaker wrote:

> Is there such a thing?
>
> I have some duplicate methods in my models, can I place them somewhere
> and call them in to my models, thus keeping DRY?

This is what inheritance is for.

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
0f9185fe8843835a97511344077dd43e?d=identicon&s=25 Andy (Guest)
on 2006-02-22 07:27
Someone tell Eric about modules :-)
4005a47a8f2ceee49670b920593c1d52?d=identicon&s=25 Ben Munat (Guest)
on 2006-02-22 08:34
(Received via mailing list)
Eric Hodel wrote:
> On Feb 21, 2006, at 2:01 PM, James Whittaker wrote:
>
>> Is there such a thing?
>>
>> I have some duplicate methods in my models, can I place them somewhere
>> and call them in to my models, thus keeping DRY?
>
>
> This is what inheritance is for.
>
Yes, really... I'm still pretty new to rails but this advice of "put
your common model
behavior in a mixin" while models have to inherit from the framework's
ORM solution just
seems absolutely bass-ackwards!

Some day I will learn enough rails/ruby to make ActiveRecord (or Og) a
mixin and have my
simple POROs (plain ol ruby objects) left totally untouched by the
framework. :-)

b
37641533d39c169de08d16c246b0f56a?d=identicon&s=25 Jack Davis (Guest)
on 2006-02-22 09:17
Another option in an intermediate class:

modela < basemodel < activerecord.

I think Dave Thomas blogged about doing just such a thing in an import
scenario.

Jack
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-02-23 00:52
(Received via mailing list)
On Feb 21, 2006, at 10:27 PM, Andy wrote:

> Someone tell Eric about modules :-)

You must like overly-complex overly-obfuscated code then.

You can't easily add validations with modules, you can with inheritance.

You can't easily add relationships with modules, you can with
inheritance.

You can't easily override base class methods via modules, you can
with inheritance.

I've been writing Ruby a long time, and I've found that use of
included, extended, append_features and alias are best used when you
need to be clever and can't use features like inheritance to
accomplish your goals.  After all, Ruby is an OO language, so if you
treat it as such it will help you accomplish your goals without
getting in your way.

When you are frequently use append_features or extended or included
you add complexity you don't need which ultimately leads to confusion
when you need to figure out what you did last week, last month or
last year.

You're also violating DRY when you use the module and class callbacks
and alias instead of inheritance because the language built
inheritance in for you.  There's no need for you to go behind the
language's back.

Compare inheritance:

class Mine < Theirs
   def my_method(some_arg)
     super(some_arg + 1)
   end
end

Simple, elegant, expressive and short, only 5 total lines to override
my_method to provide custom behavior.

With modules:

module AddOne
   def self.included(klass)
     klass.class_eval do
       alias_method :my_method_without_add, :my_method
       alias_method :my_method, :my_method_with_add
     end
   end

   def my_method_with_add(some_arg)
     my_method_without_add(some_arg + 1)
   end
end

class Theirs
   include AddOne
end

This is much longer, 14 lines, and much more difficult to figure out
if you want to change the behavior at a future date.

This also raises many questions:

What classes can AddOne be applied to?

By looking at class Theirs, what behavior can I depend upon when
calling my_method?

What do I do if I want to extend the behavior of my_method twice?
Does order of include matter?  If I call include from the same file
as the module I've pushed the dependencies down to the order of require.

(This is especially bad, order of requires should not be important to
correct functioning of your code, they should just enumerate the
transitive closure for your dependencies.)

Unlike Comparable or Enumerable which have well-defined and
unchanging features, custom modules are likely to incorporate a large
set of functionality so you lose information about the functionality
of your program because either:

You call include from your only class definition so don't know what
include will ultimately do.

You call include from the module definition file, so don't know that
include was called at all.

Now you have to look in two places to determine what a given method
will do, but you may not even know to look.

Refactoring is harder because your dependencies are spread out too much.

I'd rather reserve my fancy Module and Class callbacks for the places
I really need them, like MuffDaddy.

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
429500a5a54600958c9c7ac032a37f66?d=identicon&s=25 Joe (Guest)
on 2006-02-23 01:03
Eric Hodel wrote:
> I'd rather reserve my fancy Module and Class callbacks for the places
> I really need them, like MuffDaddy.

OK, I'll ask: what does MuffDaddy do?

Joe
4005a47a8f2ceee49670b920593c1d52?d=identicon&s=25 Ben Munat (Guest)
on 2006-02-23 07:19
(Received via mailing list)
Well stated.

So, how do you feel about models inheriting from ActiveRecord rather
than having
persistence mixed-in?

b
4daf0b71d5d9a3882e583c0e72eaf5dc?d=identicon&s=25 Alan Francis (Guest)
on 2006-02-23 15:33
Eric Hodel wrote:
> On Feb 21, 2006, at 2:01 PM, James Whittaker wrote:
>
>> Is there such a thing?
>>
>> I have some duplicate methods in my models, can I place them somewhere
>> and call them in to my models, thus keeping DRY?
>
> This is what inheritance is for.

Hmmmm.   I'd suggest this is not what inheritance is *for*.  Inheritance
is a necessary mechanism for polymorphism is some languages, and a
mechanism for varying behaviour.  If I need to be able to not care
whether its a Person or Company, all I care about is that it has methods
for manipulating the address, I can have an Addressable base class and
hey presto, polymorphism.  I can also vary the behaviour in the
subclasses (as you point out in a later post).

In removing duplicated code in a class, you can either use "Extract
Superclass" or just plain old "Extract Class" and which way I go very
much depends on exactly what those duplicate methods are.

Inheritance may be the way to go here, if it looks like both those
models may need to vary the behaviour (no need to worry about the
polymorphic angle thanks to duck typing! :).

If, however, the methods are orthogonal to the Model classes, it could
be more sensible to pull them out into a class of their own, and
aggregate as necessary, or as a Module, and mixin as necessary.

I'm not saying you're wrong, Eric, just that you're not necessarily
right :-)

James, are you at liberty to give us a flavour of the nature of the
duplication ?
A.
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-02-24 06:42
(Received via mailing list)
On Feb 22, 2006, at 4:03 PM, Joe wrote:

> Eric Hodel wrote:
>> I'd rather reserve my fancy Module and Class callbacks for the places
>> I really need them, like MuffDaddy.
>
> OK, I'll ask: what does MuffDaddy do?

Its the ultimate rapper.

http://blog.zenspider.com/archives/2005/02/muffdad...

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
This topic is locked and can not be replied to.