Forum: Ruby on Rails helper for model?

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.
Roy P. (Guest)
on 2009-01-15 03:27
(Received via mailing list)
Hey All,

I find I'm writing a ton of nearly identical model methods to support
mass creation/update of child objects (a la the 'complex forms' series
of railscasts).  Stuff like:

  def existing_child_attributes=(updated_kids)
    children.each do |kid|
      unless kid.new_record?
        atts = updated_kids[kid.id.to_s]
        if atts
          kid.attributes = atts
          kid.save
        else
          children.delete(kid)
        end
      end
    end
  end

And likewise for a new_child_attributes= method.

I'd like to write these methods once generically & call the generic
versions from the various models where I need to do this.  But it seems
that helper methods aren't visible from within a model (right?).  Where
can I put these generic methods so that they're visible from my models?
I'm using rails 2.0.2.

Thanks!

-Roy

Roy P.
Research Analyst/Programmer
Group Health Center For Health Studies (Cancer Research Network)
(206) 287-2078
Google Talk: rpardee
Brandon K. (Guest)
on 2009-01-15 05:20
(Received via mailing list)
On Wed, Jan 14, 2009 at 8:26 PM, Pardee, Roy 
<removed_email_address@domain.invalid> wrote:
>          kid.attributes = atts
> I'd like to write these methods once generically & call the generic versions from the 
various models where I need to do this.  But it seems that helper methods aren't visible 
from within a model (right?).  Where can I put these generic methods so that they're 
visible from my models?  I'm using rails 2.0.2.
You may want to check out the attribute_fu plugin:
http://github.com/giraffesoft/attribute_fu/commits/master

This wraps up this pattern cleaner than I could in my vain attempts.
It also provides some view helpers for displaying the models.

-- Brandon
--------------------------------------------------------------------------------
Training by Collective Idea: Ruby on Rails training in a vacation
setting
http://training.collectiveidea.com – San Antonio, TX – Jan 20-23
Joshua A. (Guest)
on 2009-01-15 07:18
I just posted a similar question regarding best practices when you have
methods you want to share across multiple AR models.

I ended up writing a module and sticking it in the lib directory. In
order to make these methods available to your models, simply include it
with:

class Post < ActiveRecord::Base
  include MyModule
end

That seems to be a very neat and clean way to juggle these methods and
DRY up your model code somewhat.

-- Josh
http://iammrjoshua.com


Brandon K. wrote:
> On Wed, Jan 14, 2009 at 8:26 PM, Pardee, Roy <removed_email_address@domain.invalid> 
wrote:
>>          kid.attributes = atts
>> I'd like to write these methods once generically & call the generic versions from the 
various models where I need to do this.  But it seems that helper methods aren't visible 
from within a model (right?).  Where can I put these generic methods so that they're 
visible from my models?  I'm using rails 2.0.2.
> You may want to check out the attribute_fu plugin:
> http://github.com/giraffesoft/attribute_fu/commits/master
>
> This wraps up this pattern cleaner than I could in my vain attempts.
> It also provides some view helpers for displaying the models.
>
> -- Brandon
> --------------------------------------------------------------------------------
> Training by Collective Idea: Ruby on Rails training in a vacation
> setting
> http://training.collectiveidea.com � San Antonio, TX � Jan 20-23
Ar C. (Guest)
on 2009-01-15 19:32
Another option is to inject an abstract class model between AR and the
rest of your models.

"some class" < GenericModel < ActiveRecord

where GenericModel implements all manner of standard infrastructure
functionality that is written once. Very easy for a specific model to
override default behaviors if necessary.

Did the same thing with my controllers as well.
Roy P. (Guest)
on 2009-01-16 18:38
(Received via mailing list)
Ah yes--I see that thread now--thanks!

I'm on an airplane & can't this minute check out the plugin Brandon
recommends, so I figured I'd try out the module approach you mention &
am having trouble.

I've got a file /lib/model_helper.rb w/the following contents:

  module ModelHelper
    def pretend_helper(msg)
      puts(msg)
    end
  end

And a model in care_phase.rb that starts out like:

  class CarePhase < ActiveRecord::Base
    include ModelHelper

    pretend_helper("hi!")

If I then open the console & type CarePhase.new I get this here:

  Loading development environment (Rails 2.0.2)
  >> CarePhase.new
  NoMethodError: undefined method `pretend_helper' for CarePhase(id:
integer, name: string):Class
          from
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1532:in
`method_missing'
          from C:/railsapps/collabtrac/app/models/care_phase.rb:9
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in
`load_without_new_constant_marking'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in
`load_file'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
`new_constants_in'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in
`load_file'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in
`require_or_load'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in
`load_missing_constant'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in
`const_missing'
          from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in
`const_missing'
          from (irb):1


Can anybody say what I'm doing wrong?

Thanks!

-Roy
Joshua A. (Guest)
on 2009-01-16 19:15
Yes. In your module you've defined an instance method not a class
method.

But this:

>   class CarePhase < ActiveRecord::Base
>     include ModelHelper
>
>     pretend_helper("hi!")

Is the class trying to call the method, which fails because the class
doesn't know about the 'pretend_helper' method.


What you have would work fine if you did this:

CarePhase.new.pretend_helper('hi')


If you really do want a class method, try changing the method definition
in PretendHelper to:

def self.pretend_helper(msg)
  puts msg
end

And then you would be fine to call:

CarePhase.pretend_helper('hi')

Hope that helps.

-- Josh
http://iammrjoshua.com


Roy P. wrote:
> Ah yes--I see that thread now--thanks!
>
> I'm on an airplane & can't this minute check out the plugin Brandon
> recommends, so I figured I'd try out the module approach you mention &
> am having trouble.
>
> I've got a file /lib/model_helper.rb w/the following contents:
>
>   module ModelHelper
>     def pretend_helper(msg)
>       puts(msg)
>     end
>   end
>
> And a model in care_phase.rb that starts out like:
>
>   class CarePhase < ActiveRecord::Base
>     include ModelHelper
>
>     pretend_helper("hi!")
>
> If I then open the console & type CarePhase.new I get this here:
>
>   Loading development environment (Rails 2.0.2)
>   >> CarePhase.new
>   NoMethodError: undefined method `pretend_helper' for CarePhase(id:
> integer, name: string):Class
>           from
> c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1532:in
> `method_missing'
>           from C:/railsapps/collabtrac/app/models/care_phase.rb:9
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in
> `load_without_new_constant_marking'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in
> `load_file'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in
> `new_constants_in'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in
> `load_file'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in
> `require_or_load'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in
> `load_missing_constant'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in
> `const_missing'
>           from
> 
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in
> `const_missing'
>           from (irb):1
>
>
> Can anybody say what I'm doing wrong?
>
> Thanks!
>
> -Roy
Roy P. (Guest)
on 2009-01-18 21:21
(Received via mailing list)
Ah, of course--thanks!  I do want an instance method I think--want to
call the generics from instance methods in the class.  I will
experiment.

Thanks!

-Roy
This topic is locked and can not be replied to.