Rails:使用关联时,不会在模型上调用 method_missing
我当前的代码:
class Product < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
def method_missing name
true
end
end
Category.new.ex_undefined_method #=> true
Product.last.category.ex_undefined_method #=> NoMethodError: undefined method `ex_undefined_method' for #<ActiveRecord::Associations::BelongsToAssociation:0xc4cd52c>
发生这种情况是因为 Rails 中的代码仅传递模型存在的方法。
private
def method_missing(method, *args)
if load_target
if @target.respond_to?(method)
if block_given?
@target.send(method, *args) { |*block_args| yield(*block_args) }
else
@target.send(method, *args)
end
else
super
end
end
end
这就是我想要的:
Product.last.category.ex_undefined_method #=> true
我怎样才能实现这个目标?
My current code:
class Product < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
def method_missing name
true
end
end
Category.new.ex_undefined_method #=> true
Product.last.category.ex_undefined_method #=> NoMethodError: undefined method `ex_undefined_method' for #<ActiveRecord::Associations::BelongsToAssociation:0xc4cd52c>
This happens because of this code in rails which only passes methods that exist to the model.
private
def method_missing(method, *args)
if load_target
if @target.respond_to?(method)
if block_given?
@target.send(method, *args) { |*block_args| yield(*block_args) }
else
@target.send(method, *args)
end
else
super
end
end
end
This is what I want:
Product.last.category.ex_undefined_method #=> true
How can I accomplish this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请注意,
AssociationProxy
对象仅发送目标声明为respond_to?
的方法。因此,这里的修复方法是同时更新respond_to?
:事实上,如果重新定义
method_missing,您应该始终更新
- 您已经更改了类的接口,因此您需要确保每个人都知道它。请参阅此处。respond_to?
Note that the
AssociationProxy
object only sends on methods that the target claims torespond_to?
. Therefore, the fix here is to updaterespond_to?
as well:In fact, you should always update
respond_to?
if you redefinemethod_missing
- you've changed the interface of your class, so you need to make sure that everyone knows about it. See here.乔利特的回应恕我直言,这确实是一条路。
但是,如果您使用的是 Rails 3*,请确保包含第二个参数 这已在responds_to? 中介绍过定义:
Chowlett's response is indeed the way to go imho.
But, if you are using Rails 3*, make sure to include the second argument that has been introduced in the responds_to? definition:
替换
为
AssociationProxy 的 As Monkey 补丁
Replace
by
As monkey patch to the AssociationProxy