Helper for models?

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?

Put them in a superclass?

Tony

Hello James,

2006/2/21, James W. [email protected]:

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 !

Someone tell Eric about modules :slight_smile:

On Feb 21, 2006, at 2:01 PM, James W. 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 H. - [email protected] - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Eric H. wrote:

On Feb 21, 2006, at 2:01 PM, James W. 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. :slight_smile:

b

Another option in an intermediate class:

modela < basemodel < activerecord.

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

Jack

Eric H. 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

On Feb 21, 2006, at 10:27 PM, Andy wrote:

Someone tell Eric about modules :slight_smile:

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 H. - [email protected] - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Well stated.

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

b

Eric H. wrote:

On Feb 21, 2006, at 2:01 PM, James W. 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 :slight_smile:

James, are you at liberty to give us a flavour of the nature of the
duplication ?
A.

On Feb 22, 2006, at 4:03 PM, Joe wrote:

Eric H. 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/muffdaddy_the_u.html


Eric H. - [email protected] - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com