gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 08:44:31 24 4
gpt4 key购买 nike

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

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com