2

I've just seen this line of Ruby code in ruby-trello:

# Returns the member who created the action.
one :member_creator, :via => Member, :using => :member_creator_id

It seems to relate to a superclass method defined as:

def self.one(name, opts = {})
  class_eval do
    define_method(:"#{name}") do |*args|
      options = opts.dup
      klass   = options.delete(:via) || Trello.const_get(name.to_s.camelize)
      ident   = options.delete(:using) || :id
      klass.find(self.send(ident))
    end
  end
end

I understand that class_eval relates to reflection.

Could someone please explain the purpose of the subclass code line?

My guess would be that it's calling the class member one passing :member_creator as name and the two trailing args as the opts argument. But why would this be called at the class level?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
KomodoDave
  • 7,239
  • 10
  • 60
  • 92
  • I can tell you what that method does. It defines a method dynamically at runtime. As for the purpose, I'm not sure. – Sergio Tulentsev Dec 03 '12 at 16:43
  • @Dogbert "subclass code line" = "line of code from the subclass". Just as "sharp pencil" = "pencil that is sharp" or "dog bowl" = "bowl for the dog". – KomodoDave Dec 03 '12 at 16:45
  • @Sergio Thank you for your response. I was being blind, see my response to Teddy's answer below. – KomodoDave Dec 03 '12 at 16:50

1 Answers1

2

It is appears to be a way to DRY up some code used to find a single record by primary key.

You basically pass a class/model name and a method used to get the primary key.

This code:

one :member_creator, :via => Member, :using => :member_creator_id

Creates this method:

def member_creator 
  Member.find(self.member_creator_id)
end
Teddy
  • 18,357
  • 2
  • 30
  • 42
  • Yes of course - I'm being blind through fatigue. I was aware the superclass definition used `class_eval` to dynamically define a method, but obviously you have to call it to have that method defined. Duh! I'll mark your answer as correct when I'm able to in 5 mins, thank you Teddy. – KomodoDave Dec 03 '12 at 16:48
  • p.s. Why wouldn't the author have written it as `one(:member_creator,{:via => Member, :using => :member_creator_id})`? Is my form syntactically correct? It's how I would have written it, but I'm fairly new to Ruby and don't know the caveats of symbols. – KomodoDave Dec 03 '12 at 16:49
  • They are both correct, but Rubyist tend to take a "less is more" attitude. It is a matter of personal preference and consideration of other programmers who will have to maintain the code in the future. – Teddy Dec 03 '12 at 16:53
  • Ok, message understood. I didn't know you could splat hash operators like that for an argument, interesting! I would have written my own way for clarity. Thank you for responding again Teddy, much appreciated. – KomodoDave Dec 03 '12 at 17:14
  • `but Rubyist tend to take a "less is more" attitude` ... + for the attitude – Baba Dec 05 '12 at 18:09