【问题标题】:Where to put my ruby class class "meta-generator"?将我的 ruby​​ 类“元生成器”放在哪里?
【发布时间】:2011-03-21 23:47:55
【问题描述】:

我有以下几点:

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 }

但是,每次我刷新使用第三方对象的页面时,控制台都会输出“In generator method”行。

我尝试了几件事: 将 has_many_children_of_kind 放在我的应用程序初始化程序中,而不是将其放在 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
    }
  )
}

什么是最好的?评估版还是最新版?我会说最新的,因为不涉及解析器/评估,所以它可能会快一点,对吧?

【问题讨论】:

  • 尝试在 development.rb 中设置 config.cache_classes = true。很可能您只是看到每个请求都会重新加载类。
  • 这是一个实际可行的解决方案!非常感谢,我不知道这种缓存机制。

标签: ruby-on-rails metaprogramming


【解决方案1】:

MikeOnRails 指出了一个很好的答案。

【讨论】:

    猜你喜欢
    • 2014-11-01
    • 2011-08-02
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    相关资源
    最近更新 更多