如何在创建对象之前修改参数

时间:2015-09-30 13:42:33

标签: ruby-on-rails ruby strong-parameters

我使用嵌套属性来创建PhotoComment对象。我想在评论中设置作者,评论嵌套在照片中。

以下是参数:

photo: {
  file: 'hi.jpg',
  comments_params: [
    { content: "hello world!" }
  ]
}

但我想将作者添加到评论中。

  # ...
  comments_params: [
    { content: "hello world!", author: current_user }
  ]
  # ...

最简单的方法是什么?我的控制器代码看起来像这样。

@photo = Photo.new(photo_params)
@photo.save!

private

def photo_params
  params.require(:photo).permit(:file, comments_attributes: [:content])
end

我可以通过使用strong_parameters过滤它们来操纵参数(伪代码,但这个想法是站立的),但我宁愿不这样做。

photo_params[:comments_attributes].each do |comment|
  comment[:author] = current_user
end

但这感觉有点不对劲。

3 个答案:

答案 0 :(得分:2)

您可以将作者分配给现有的对象,而不是使用params;

@photo = Photo.new(photo_params)
@photo.comments.select(&:new_record?).each {|c| c.author = current_user }
@photo.save!

答案 1 :(得分:1)

我认为你不愿意这样做的方式没有任何问题。

您也可以某种方式使用标准Hash#mergemerge!ActiveSupport's deep_mergedeep_merge!

评论是一个可能很多的数组的事实使得很难很好地做到这一点。

我想我会复制原始参数而不是编辑它们 - 这对你来说有什么不对吗? ActiveSupport's deep_dup可能会有所帮助。

如下:

photo_params = photo_params.deep_dup
photo_params[:comments_attributes] = photo_params[:comments_attributes].collect {|c| c.merge(:author => :current_user)}
@photo = Photo.new(photo_params)
...

我不确定这是不是更好。但也许它会让您了解一些可供您使用的工具。

答案 2 :(得分:0)

您可以在评论表单中添加隐藏字段。

<%= f.hidden_field :user_id, :value => current_user.id %>