使用 "update" 方法后,为 Rails 中的未定义属性调用 method_missing
Calling method_missing for undefined attributes in Rails after using "update" method
是否有 obj.update(attr1: "something")
方法调用 method_missing
而不是引发错误 ActiveModel::UnknownAttributeError (unknown attribute 'attr1' for Obj.)
的捷径?
我正在考虑简单地拯救它,然后 mimicking/calling method_missing,但这种方式感觉太笨重了。
是这样的吗?
rescue_from ActiveModel::UnknownAttributeError do |exception|
raise NoMethodError
# or however you want to hanle
end
你可以试试这个:
begin
obj.update(attr1: "something")
rescue Exception => ex
if ex.class == ActiveRecord::UnknownAttributeError
method_missing
else
raise ex
end
end
从 source code (Rails 4.2) it seems that ActiveRecord::UnknownAttributeError
is raised when the model instance does not respond_to?
to the given attribute setter. So what you have to do is define a method_missing
as well as respond_to_missing?
in the model for all your dynamic attributes. This is actually what you always should do 无论如何使用 method_missing
时:
class Model < ActiveRecord::Base
DYNAMIC_ATTRIBUTES = [:attr1, :attr2]
def method_missing(method_name, *arguments, &block)
if DYNAMIC_ATTRIBUTES.map { |attr| "#{attr}=" }.include?(method_name.to_s)
puts "custom code for #{method_name} #{arguments.first.inspect}"
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
DYNAMIC_ATTRIBUTES.map { |attr| "#{attr}=" }.include?(method_name.to_s) || super
end
end
在 Rails 控制台中测试:
Model.first.update(attr1: 'aa', attr2: 'bb')
# => custom code for attr1= "aa"
# => custom code for attr2= "bb"
Model.first.update(attr1: 'aa', attr2: 'bb', attr3: 'cc')
# => ActiveRecord::UnknownAttributeError: unknown attribute 'attr3' for Model.
是否有 obj.update(attr1: "something")
方法调用 method_missing
而不是引发错误 ActiveModel::UnknownAttributeError (unknown attribute 'attr1' for Obj.)
的捷径?
我正在考虑简单地拯救它,然后 mimicking/calling method_missing,但这种方式感觉太笨重了。
是这样的吗?
rescue_from ActiveModel::UnknownAttributeError do |exception|
raise NoMethodError
# or however you want to hanle
end
你可以试试这个:
begin
obj.update(attr1: "something")
rescue Exception => ex
if ex.class == ActiveRecord::UnknownAttributeError
method_missing
else
raise ex
end
end
从 source code (Rails 4.2) it seems that ActiveRecord::UnknownAttributeError
is raised when the model instance does not respond_to?
to the given attribute setter. So what you have to do is define a method_missing
as well as respond_to_missing?
in the model for all your dynamic attributes. This is actually what you always should do 无论如何使用 method_missing
时:
class Model < ActiveRecord::Base
DYNAMIC_ATTRIBUTES = [:attr1, :attr2]
def method_missing(method_name, *arguments, &block)
if DYNAMIC_ATTRIBUTES.map { |attr| "#{attr}=" }.include?(method_name.to_s)
puts "custom code for #{method_name} #{arguments.first.inspect}"
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
DYNAMIC_ATTRIBUTES.map { |attr| "#{attr}=" }.include?(method_name.to_s) || super
end
end
在 Rails 控制台中测试:
Model.first.update(attr1: 'aa', attr2: 'bb')
# => custom code for attr1= "aa"
# => custom code for attr2= "bb"
Model.first.update(attr1: 'aa', attr2: 'bb', attr3: 'cc')
# => ActiveRecord::UnknownAttributeError: unknown attribute 'attr3' for Model.