Rails 4:将属性插入参数


68

在Rails 3中,可以将属性插入到参数中,如下所示:

params[:post][:user_id] = current_user.id

我正在尝试在Rails 4中做类似的事情,但是没有运气:

post_params[:user_id] = current_user.id

. . . .


private

  def post_params
    params.require(:post).permit(:user_id)
  end

Rails忽略了这种插入。它不会引发任何错误,只是会自动失败。

Answers:


143

这里找到答案。您可以通过合并将其插入到params定义中,而不是从controller动作中插入该属性。为了扩展我之前的示例:

private

  def post_params
    params.require(:post).permit(:some_attribute).merge(user_id: current_user.id)
  end

deep_merge在params构造函数中使用了@marflar ?还是控制器中的其他位置?
Brian Jordan

这也是我的操作方式,但我一直认为必须有一种方法可以将其干燥。我的50多个控制器中的所有控制器都在strict params区域中有类似的.merge语句。就我而言,我将current_user合并到updated_by中。我仅在create方法中将current_user合并到created_by中。
2014年

@Dan,我猜您使用关联,因此使用类似以下内容应该会更容易current_user.items.create(item_params)。我merge仅在有另一个关联可以创建时使用,即@comment = @commentable.comments.new(comment_params),我的comment_params方法如下所示:params.require(:comment).permit(:body, :parent_id, :removed).merge(user_id: current_user.id)
AlmirSarajčić2015年

伙计们,请看一下我的问题,如果可以的话,请帮帮我。它与以下内容紧密相关:stackoverflow.com/questions/33357501/…–
肖恩·马盖尔

如果像我一样,您正在寻找如何在params中使用自定义值,可以执行params.require(:post).permit(:some_attribute).merge(user_id:params [:post] [:id])`
eXa

39

除了@timothycommoner的答案外,您还可以基于每个操作执行合并:

  def create
    @post = Post.new(post_params.merge(user_id: current_user.id))
    # save the object etc
  end

private
  def post_params
    params.require(:post).permit(:some_attribute)
  end

2
嘿,您将如何为嵌套资源执行此操作?
Mene 2015年

我不确定为什么,但是@timothycommoner的答案对我不起作用。仅此一项...我什至尝试过merge!,但仍然失败。哦,无论如何,这听起来更容易,因为没有深入研究私有方法,并且在不同的用例中更容易更改
james 2016年

@ Patient55我想您需要deep_merge在所选答案的注释中讨论的内容。
机智

3

作为这种情况的替代方案,您可以通过scope以下方式要求pass属性:

current_user.posts.create(post_params)


0

如果有人试图弄清楚如何在Rails 5属性哈希中添加/编辑嵌套属性,我发现这是最简单的方法。不要为merge或deep_merge烦恼...由于强大的参数,这很痛苦。在此示例中,我需要在保存之前将group_id和vendor_id复制到关联的发票(嵌套参数)。

def create
  my_params = order_params
  @order = Order.new
  @order.attributes = my_params
  @order.invoice.group_id = my_params[:group_id]
  @order.invoice.vendor_id = my_params[:vendor_id]
  @order.save
end

private

# Permit like normal
def order_params
  params.require(:order).permit([:vendor_id, :group_id, :amount, :shipping,:invoice_attributes => [:invoice_number, :invoice_date, :due_date, :vendor_id, :group_id]])
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.