一些背景:我有一个带有十进制列d
的Rails 4模型。在应用程序中保存或查看时,可能需要根据当前用户的偏好将该值分别转换为整数值或从整数值转换而来。
似乎最合适的是,计算应该在模型中进行,并且不应该了解用户。
在进行了一些搜索后,在我看来,实现这一点的最佳方法是通过模型上的两个虚拟属性:一个用于当前用户的首选格式,另一个用于值,并应用任何计算。
所以我想出了这样的东西:
attr_accessor :format, :value_converted
def value_converted
if format.nil?
format = 'A'
end
if format == 'A'
Converter.new(d).to_i if d
else
d if d
end
end
def value_converted=(value)
if format.nil?
format = 'A'
end
if format == 'A'
self.d = Converter.new(value.to_i).to_f
else
self.d = value
end
表单引用的是value_converted
而不是d
,这对于编辑、更新和查看都很有效。问题出在#create
操作上。
我相信问题的发生是因为setter正在访问format
,而且我似乎无法在调用setter之前,也就是说,当new
创建对象时,找到从#create
设置format
的方法。
我想也许我可以把format
和其他参数一起传递(就像在这个答案中一样,所以我尝试将它合并到标准强参数票价之内和之后,但没有成功:
两个
@entry = current_user.entries.new(entry_params.merge(format: current_user.format))
和
params.require(:entry).permit(:value_converted, :other_param, ...).merge(format: current_user.format)
不要提出任何错误,但显然被忽略了。然而,在控制台中简单地将format
传递给new
就可以了。
所以我的问题是:有人能解决这个问题吗?或者也许是一种更好/更合适的方式?它似乎应该是一些简单的东西。
感谢您的帮助
目前,我只需在保存之前在控制器中再次设置format
和value_converted
的值:
def create
@entry = current_user.entries.new(entry_params)
@entry.format = current_user.format
@entry.value_converted = entry_params[:value_converted]
if @entry.save
...
end
虽然这可能不是最优雅的解决方案(我不知道我的实现是否是线程安全的),但它似乎确实有效。