我有一个带有几个虚拟属性设置器的ActiveRecord模型。我想构建一个对象,但不将其保存到数据库中。一个setter必须在其他人之前执行。怎么办?
作为一种解决方法,我分两步构建对象
@other_model = @some_model.build_other_model
@other_model.setup(params[:other_model)
setup
的位置:
class OtherModel < ActiveRecord::Base
def setup(other_params)
# execute the important_attribute= setter first
important_attribute = other_params.delete(:important_attribute)
# set the other attributes in whatever order they occur in the params hash
other_params.each { |k,v| self.send("#{k}=",v) }
end
end
这似乎有效,但看起来很糟糕。还有更好的方法吗?
修改
根据neutrino的建议,我向SomeModel
添加了一种方法:
class SomeModel < ActiveRecord::Base
def build_other_model(other_params)
other_model = OtherModel.new(:some_model=>self)
other_model.setup(other_params)
other_model
end
end
答案 0 :(得分:1)
使用OtherModel
方法完成此操作是件好事,因为您可以调用此方法而不用担心赋值顺序。所以我会留下这部分,但只是从SomeModel
的方法调用它:
class SomeModel < ActiveRecord::Base
def build_other_model(other_params)
other_model = build_other_model
other_model.setup(other_params)
other_model
end
end
那么你会有
@other_model = @some_model.build_other_model(params[:other_model])
答案 1 :(得分:0)
我首先想到了在设置方法中删除重要属性,但是使用了alias_chain_method来使其更加透明:
def attributes_with_set_important_attribute_first=(attributes = {})
# Make sure not to accidentally blank out the important_attribute when none is passed in
if attributes.symbolize_keys!.include?(:important_attribute)
self.important_attribute = attributes.delete(:important_attribute)
end
self.attributes_without_set_important_attribute_first = attributes
end
alias_method_chain :attributes=, :set_important_attribute_first
这样,您的代码都不会改变正常的Rails样式
@other_model = @some_model.other_models.build(params[:other_model])