Rails 4: Insert Attribute Into Params
Ruby on-RailsStrong ParametersRuby on-Rails Problem Overview
In Rails 3, it was possible to insert an attribute into params like so:
params[:post][:user_id] = current_user.id
I'm attempting to do something similar in Rails 4, but having no luck:
post_params[:user_id] = current_user.id
. . . .
private
def post_params
params.require(:post).permit(:user_id)
end
Rails is ignoring this insertion. It doesn't throw any errors, it just quietly fails.
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
Found the answer here. Rather than inserting the attribute from within the controller action, you can insert it into the params definition with a merge. To expand upon my previous example:
private
def post_params
params.require(:post).permit(:some_attribute).merge(user_id: current_user.id)
end
Solution 2 - Ruby on-Rails
In addition to @timothycommoner's answer, you can alternatively perform the merge on a per-action basis:
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
Solution 3 - Ruby on-Rails
As an alternative for this case, you can required pass attribute via scope
:
current_user.posts.create(post_params)
Solution 4 - Ruby on-Rails
If anyone is trying to figure out how to add/edit a nested attribute in a Rails 5 attributes hash, I found this to be the most straight-forward (alternate) approach. Don't bother with merge or deep_merge...it's a pain due to the strong parameters. In this example, I needed to copy the group_id and vendor_id to the associated invoice (nested parameters) prior to saving.
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