【问题标题】:Ruby Objects from gems and where to override来自 gems 的 Ruby 对象以及在哪里覆盖
【发布时间】:2014-03-06 15:25:40
【问题描述】:

所以我有一个 gem,其中包含一些 activerecord 对象,如果重要的话,它们位于单表继承层次结构中

# gem
class MySTIBaseClass < ActiveRecord::Base
  # some code, does NOT implement a default_scope
end

当我在 Rails 应用程序中尝试定义一个 default_scope

class MySTIBaseClass < ActiveRecord::Base
  default_scope :order => "my_sti_bases.name ASC"
end
class MySTIOtherClass < MySTIBaseClass
  # this is not in the gem, only in the rails application
  scope :active, { where active: true }
end
MySTIOtherClass.active # order default scope is not applied

但是,如果我没有重新打开类,而是将代码放在初始化程序中:

# initializer
MySTIBaseClass.instance_eval do
  default_scope :order => "my_sti_bases.name ASC"
end

# when the app is running
MySTIOtherClass.active # default_scope is applied

但是,我似乎无法真正理解为什么会出现这种情况。似乎在所有声明都被评估之前,MySTIOtherClass.active 不会被调用,所以在应用程序中运行的类的版本应该有所有声明的东西的完整视图。没有冲突的 default_scopes 并且它选择了最后一个声明的,所以看起来默认范围应该可以工作。

【问题讨论】:

    标签: ruby gem metaprogramming


    【解决方案1】:

    app/models 目录设置为自动加载路径。这意味着它仅在找不到符号时才需要该文件。在您的情况下,由于它已经在 gem 中定义,因此永远不会触发自动加载,这就是您没有得到 default_scope 的原因

    【讨论】:

    • 有趣!有没有办法强制rails重新加载模型?
    • 你可以这样做 Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file|初始化器中的require_dependency 文件}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多