在Rails 4中从控制器创建动作设置虚拟模型属性 - 属性总是为零

时间:2013-08-14 14:11:12

标签: ruby-on-rails model controller ruby-on-rails-4 strong-parameters

一些背景知识:我有一个带有十进制列d的Rails 4模型。在应用程序中保存或查看时,可能需要根据当前用户的偏好将值转换为整数值或从整数值转换。

似乎最合适的是计算应该放在模型中,并且应该不了解用户。

在进行一些搜索之后,在我看来,实现这一目标的最佳方法是通过模型上的2个虚拟属性:一个用于当前用户的首选格式,另一个用于值,并应用任何计算。

所以我想出了类似的东西:

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之前我似乎无法找到从format设置#create的方法,换句话说,当new创建对象时。

我想也许我可以将format和其他参数一起传递(如this answer中所示,所以我尝试将其合并,在标准强参数票价之内和之后,但没有运气:

两个

@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即可。

所以我的问题:有没有人能解决这个问题?或者更好/更合适的方式去做吧?看起来它应该是简单的东西。

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

目前,我通过在保存之前在控制器中再次设置formatvalue_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

虽然这可能不是最优雅的解决方案(我不知道我的实现是否是线程安全的)但它似乎确实有效。