开发者

Where to put my ruby class class "meta-generator"?

i have the following:

class ThirdParty < ActiveRecord::Base
  # Dynamically adds accessors of the requested kind.
  def self.has_many_children_of_kind (kinds=[])
    puts 'In generator method'
    kinds.each  { |k|
      n            = k.to_s
      self.class_eval  %{
        has_many    :#{n}_as_owner, {
                      :foreign_key  => :owner_id,
                      :class_name    => 'ThirdPartiesLink',
                      :conditions    => #{ k!=:third_parties ? "{ :kind => '"+n.singularize+"' }" : 'nil' }
                    }
        has_many    :#{n}, {
                      :through      => :#{n}_as_owner,
                      :source        => :owned
                开发者_如何学运维    }
        }
      }
  end
  # Make dynamic associations of given kinds.
  has_many_children_of_kind  [ :third_parties, :customers, :suppliers, :contacts ]
end
class ThirdPartiesLink < ActiveRecord::Base
  belongs_to  :owner,  :foreign_key => :owner_id,  :class_name => 'ThirdParty'
  belongs_to  :owned,  :foreign_key => :owned_id,  :class_name => 'ThirdParty'
  # This model has a column named 'kind' for storing the link kind.
end

Everything is working exactly as i expect. The line:

has_many_children_of_kind [ :third_parties, :customers, :suppliers, :contacts ]

Generates:

has_many :third_parties_as_owner, { :foreign_key => :owner_id, :class_name => 'ThirdPartiesLink', :conditions => nil }
has_many :third_parties, { :through => :third_parties_as_owner, :source => :owned } 
has_many :customers_as_owner, { :foreign_key => :owner_id, :class_name => 'ThirdPartiesLink', :conditions => { :kind => 'customer' } }
has_many :customers, { :through => :customers_as_owner, :source => :owned } 
has_many :suppliers_as_owner, { :foreign_key => :owner_id, :class_name => 'ThirdPartiesLink', :conditions => { :kind => 'supplier' } }
has_many :suppliers, { :through => :suppliers_as_owner, :source => :owned } 
has_many :contacts_as_owner, { :foreign_key => :owner_id, :class_name => 'ThirdPartiesLink', :conditions => { :kind => 'contact' } }
has_many :contacts, { :through => :contacts_as_owner, :source => :owned }

However, each time i refresh a page in which the ThirdParty object is used, the line 'In generator method' gets outputed in the console.

i have tried several things: puting the has_many_children_of_kind in my application initializers instead of putting it in the ThirdParty class (i really don't like that, it was more of a test than anything else). In this case, the first display of a page works after the server is restarted, but then if i refresh the page, the generated methods are not found when called on a ThirdParty instance...

What would be the way to make sure the ThirdParty class gets written with the accessors once for all at startup of the server?

Thanks for your time! Pierre.

Edit: The generator method block could also be like this:

kinds.each  { |k|
  n            = k.to_s
 has_many("#{n}_as_owner".to_sym, {
      :foreign_key  => :owner_id,
      :class_name   => 'ThirdPartiesLink',
      :conditions   => ( k!=:third_parties ? { :kind => n.singularize } : nil)
    }
  )
 has_many(n.to_sym, {
      :through      => "#{n}_as_owner".to_sym,
      :source       => :owned
    }
  )
}

What is the best? The eval or the latest? i'd say the latest, because no parser / eval is involved, so it's probably a bit faster, right?


A good answer is the one pointed out by MikeOnRails.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜