为什么这个继承自 ActiveRecord::Base 的 class 不能 class_eval 作用域
Why is this class which inherits from ActiveRecord::Base incapable of class_eval ing scope
注意:我知道我在这里做的事情可能很愚蠢,但我什至不一定要使用这段代码我现在只是好奇。
如果 class
上缺少特定方法,我正在尝试将一个空的 Rails 作用域动态添加到 class
这份文件似乎特别表明这应该是可能的:https://api.rubyonrails.org/classes/ActiveSupport/Concern.html
module Mod
extend ActiveSupport::Concern
class_methods do
def method_missing(m, *args, &block)
if m.match? /method/
klass = class << self; self; end
klass.class_eval { scope :method, -> {} }
end
end
end
end
klass 在这里正确设置为 class 但是尝试评估范围的创建失败 undefined method 'scope' for #<Class:0x0000560e35d2eb48>
但是当我调用 klass.ancestors
我可以确认 klass 继承自ActiveRecord::Base
并且应该有作用域。
为什么我不能在这里 class_eval
scope
的任何想法
假设有一个 class Person < ActiveRecord::Base
将包含您的模块 Mod
。
在 Ruby 中,继承层次结构如下所示(水平超 class 链):
Class Class
| |
Person -superclass-> ActiveRecord::Base
所以 Person.class
不会 return ActiveRecord::Base
而是 Class:Person
(上面的垂直链),这意味着你的代码 kclass = class << self; self; end
实际上 return Person.class
是 Class:Person
- 一个 Class 对象,与 ActiveRecord::Base 没有任何关系 - 所以它不会 respond_to? :scope
module Mod
extend ActiveSupport::Concern
class_methods do
# override Person#method_missing
def method_missing(m, *args, &block)
# anytime call Person.a_method_that_not_be_defined
puts self # Person
kclass = class << self; self; end # <--- Class:Person
所以在这种情况下,您应该使用 self.class_eval
而不是 kclass.class_eval
。
注意:我知道我在这里做的事情可能很愚蠢,但我什至不一定要使用这段代码我现在只是好奇。
如果 class
上缺少特定方法,我正在尝试将一个空的 Rails 作用域动态添加到 class这份文件似乎特别表明这应该是可能的:https://api.rubyonrails.org/classes/ActiveSupport/Concern.html
module Mod
extend ActiveSupport::Concern
class_methods do
def method_missing(m, *args, &block)
if m.match? /method/
klass = class << self; self; end
klass.class_eval { scope :method, -> {} }
end
end
end
end
klass 在这里正确设置为 class 但是尝试评估范围的创建失败 undefined method 'scope' for #<Class:0x0000560e35d2eb48>
但是当我调用 klass.ancestors
我可以确认 klass 继承自ActiveRecord::Base
并且应该有作用域。
为什么我不能在这里 class_eval
scope
的任何想法
假设有一个 class Person < ActiveRecord::Base
将包含您的模块 Mod
。
在 Ruby 中,继承层次结构如下所示(水平超 class 链):
Class Class
| |
Person -superclass-> ActiveRecord::Base
所以 Person.class
不会 return ActiveRecord::Base
而是 Class:Person
(上面的垂直链),这意味着你的代码 kclass = class << self; self; end
实际上 return Person.class
是 Class:Person
- 一个 Class 对象,与 ActiveRecord::Base 没有任何关系 - 所以它不会 respond_to? :scope
module Mod
extend ActiveSupport::Concern
class_methods do
# override Person#method_missing
def method_missing(m, *args, &block)
# anytime call Person.a_method_that_not_be_defined
puts self # Person
kclass = class << self; self; end # <--- Class:Person
所以在这种情况下,您应该使用 self.class_eval
而不是 kclass.class_eval
。