Forum: Ruby on Rails Dynamically adding class methods to 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.
55ff1426273f950b43135f619d025476?d=identicon&s=25 Todd Runstein (todd_run)
on 2007-06-06 23:00
I have a Model that includes a bunch of class methods.  I want to be
able to make calls like:

calories = Nutrient.calories
fat = Nutrient.fat

Right now, my Model looks like something I'd write in Java:

class Nutrient < ActiveRecord::Base

  def self.calories
    Nutrient.find(208)
  end

  def self.fat
    Nutrient.find(204)
  end

  ...This goes on for awhile...
end


I need help taking advantage of Ruby. I'd like something like:

class Nutrient < ActiveRecord::Base
  NUTRIENTS = {"calories" => 208, "fat" => 204, ...

  def self.method_missing(methodname, *args)
    value = NUTRIENTS[methodname)
    Nutrient.find(value) unless value.nil?
  end

end


I've tried many permutations of dynamically adding these methods, but I
hit a brick wall every time.  Can someone give me some direction?

Thanks in advance
588ab1c0a5610a7e160a3b101abb91e6?d=identicon&s=25 MichaelLatta (Guest)
on 2007-06-06 23:48
(Received via mailing list)
Look at class_eval for creating class methods on the fly.  Or extend
the class with a module that defines method_missing in the module.

Michael



On Jun 6, 2:00 pm, Todd Runstein <rails-mailing-l...@andreas-s.net>
55ff1426273f950b43135f619d025476?d=identicon&s=25 Todd Runstein (todd_run)
on 2007-06-07 00:36
MichaelLatta wrote:
> Look at class_eval for creating class methods on the fly.  Or extend
> the class with a module that defines method_missing in the module.
>
> Michael
>
>
>
> On Jun 6, 2:00 pm, Todd Runstein <rails-mailing-l...@andreas-s.net>

Hell yeah!

I tried class_eval earlier but kept getting "stack too deep" errors.
I'm not sure what I was doing wrong, but I remember it was frustrating,
so I abandoned that approach.  Your suggestion prompted me to try again
- Thank you!

Here's what I've got now:

class Nutrient < ActiveRecord::Base
  NUTRIENTS = {"calories" => "ENERC_KAL", "fat" => "FAT", ...

  NUTRIENTS.each do | key, value |
    class_eval "def self.#{key} ; Nutrient.find_by_tagname('#{value}') ;
end ;"
  end

  ... no more messy methods! ...
end

It's so beautiful it makes me want to cry.  Thanks again Michael!
This topic is locked and can not be replied to.