Где разместить мой класс ruby ​​class "meta-generator"? - PullRequest
1 голос
/ 22 марта 2011

У меня есть следующее:

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

Все работает точно так, как я ожидаю.Строка:

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

Генерирует:

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 }

Однако каждый раз, когда я обновляю страницу, на которой используется объект ThirdParty, строка «В генераторе» выводится вconsole.

Я пробовал несколько вещей: поместить has_many_children_of_kind в инициализаторы моего приложения вместо того, чтобы помещать его в класс ThirdParty (мне это действительно не нравится, это был скорее тест, чем что-либо еще).В этом случае первое отображение страницы работает после перезапуска сервера, но затем, если я обновлю страницу, сгенерированные методы не будут найдены при вызове экземпляра ThirdParty ...

Что будетспособ убедиться, что класс ThirdParty будет записан с аксессорами раз и навсегда при запуске сервера?

Спасибо за ваше время!Пьер.

Редактировать: Блок метода генератора также может быть таким:

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
    }
  )
}

Что лучше?Eval или последний?Я бы сказал, что последнее, потому что парсер / eval не задействован, так что, вероятно, он немного быстрее, верно?

1 Ответ

0 голосов
/ 24 марта 2011

Хороший ответ тот, который указал MikeOnRails.

...