ruby-on-rails - 在 Rails 3 中使用命名空间模型时,类方法仅包含一次

标签 ruby-on-rails ruby ruby-on-rails-3 activesupport-concern

我的文件夹结构如下所示:

app/models/
    concerns/
        quxable.rb
    foo/
        bar.rb
        baz.rb

我使用的是 Rails 3,所以我自动加载了我的担忧:

config.autoload_paths += Dir[Rails.root.join('app', 'models', "concerns", '**/')]

文件如下:

quxable.rb

module Quxable
    extend ActiveSupport::Concern        

    module ClassMethods
        def new_method
        end
    end
end

bar.rb

class Foo::Bar < ActiveRecord::Base
    include Quxable
end

baz.rb

class Foo::Baz < ActiveRecord::Base
    include Quxable
end

现在,如果在控制台中执行此操作,我会得到以下输出:

Foo::Bar.respond_to? :new_method #=> true
Foo::Baz.respond_to? :new_method #=> false
reload!
Foo::Baz.respond_to? :new_method #=> true
Foo::Bar.respond_to? :new_method #=> false

因此,它似乎只能正确包含在首次访问的模型中。然而,如果我运行以下命令:

ActiveRecord::Base.descendants.select{ |c| c.included_modules.include?(Quxable) }.map(&:name)

我得到["Foo::Bar", "Foo::Baz"]

知道这是怎么回事吗?我猜测与自动加载/急切加载有关,但我不确定为什么这两个模型都没有获得新的类方法。

PS - 我尝试在没有 ActiveSupport::Concern 的情况下重写模块(只是因为我使用的是旧 Rails 版本并且我在黑暗中拍摄)使用:

def include(base)
    base.send :extend, ClassMethods
end

但我仍然遇到同样的问题。

编辑

我最初忽略了这一点(只是想提出最简单的问题),所以我向那些之前试图提供帮助的人道歉。但 quxable.rb 实际上看起来像这样:

module Quxable
    extend ActiveSupport::Concern 

    LOOKUP = {
        Foo::Bar => "something",
        Foo::Baz => "something else"
    }

    module ClassMethods
        def new_method
        end
    end
end

所以我猜我创建了某种循环依赖关系,用 Class 对象定义了一个常量。有人能证实吗?奇怪的是,由于没有在第二个访问的类上定义类方法,它只是默默地失败了。不知道这是为什么?

最佳答案

根据您的编辑,此代码有问题:

LOOKUP = {
    Foo::Bar => "something",
    Foo::Baz => "something else"
}

它将在模块完成之前实例化 Foo::Bar。因此 new_method 将被省略。这种情况下的传统是在查找中使用字符串,并在需要时将它们常量化以将它们转换为类。

LOOKUP = {
    "Foo::Bar" => "something",
    "Foo::Baz" => "something else"
}

然后

LOOKUP.keys.first.constantize.new_method

result = LOOKUP[Foo::Bar.name]

使用它。

关于ruby-on-rails - 在 Rails 3 中使用命名空间模型时,类方法仅包含一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34228194/

相关文章:

ruby - ActiveRecord bool 值返回 "f", "t"

javascript - 连接到 vagrant 服务器时自动运行文件

ruby-on-rails-3 - Ruby On Rails 3 中 railties 和引擎之间的差异

jquery - rails 。 Dropdown1 使用 Ruby on Rails 启用 Drobdown2 选择

ruby-on-rails - 如何在 Rails 迁移中添加一些插入?

ruby-on-rails - RSpec:关联对象的工厂定义

ruby-on-rails - 如何在生产模式下运行redis服务器和juggernaut服务器

Ruby:C类包含模块M;在 M 中包含模块 N 不会影响 C。什么给了?

ruby-on-rails - 何时在 Rails 中使用 "has_many :through"关系?

ruby-on-rails - 在 'static'子域上转换 Assets