I am migrating a Rails 3.2 app to strong_parameters and don't have much experience.
I have a model called Item which has_many attributes. In our item#update I'd like to be able to do like the following:
# Model
class Item < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
has_many :assets, :as => :assetable, :dependent => :destroy
...
#in items_controller.rb
def update
@item=Item.find(params[:id])
if @item.update_attributes(params[:item])
...
private
def item_params
params.require(:item).permit(:assets_attributes).permit!
end
How would I specify the item_params to allow an asset to be created through this update statement?
so if I pull a list of attributes via:
a=Asset.first
a.attributes
I get:
{"id"=>4424,
"name"=>nil,
"created_at"=>Fri, 24 Jan 2014 15:49:17 PST -08:00,
"updated_at"=>Fri, 24 Jan 2014 15:49:17 PST -08:00,
"asset_file_name"=>"br-3.jpg",
"asset_content_type"=>"image/jpeg",
"asset_file_size"=>198085,
"asset_updated_at"=>Fri, 24 Jan 2014 15:49:16 PST -08:00,
"menu_item_id"=>nil,
"assetable_id"=>1,
"assetable_type"=>"LocationProfileAlbum",
"global_id"=>9394,
"description"=>nil,
"associated_global_id"=>9393,
"user_id"=>nil,
"position"=>0.0,
"hash_val"=>nil,
"is_instore"=>false,
"location_id"=>nil,
"filepicker_url"=>nil}
if I then put it in:
def item_params
params.require(:item).permit(
:assets_attributes[
:id, :name, :created_at, :updated_at , :asset_file_name, :asset_content_type, :asset_file_size, :asset_updated_at, :menu_item_id, :assetable_id, :assetable_type, :global_id, :description, :associated_global_id, :user_id, :position, :hash_val, :is_instore, :location_id, :filepicker_url
]
)
and then add a file, I get the error:
ArgumentError (wrong number of arguments (20 for 1..2)):
app/controllers/items_controller.rb:218:in `[]'
app/controllers/items_controller.rb:218:in `item_params'
First, you need to specify which attributes for the nested assets are allowed, e.g.:
def item_params
params.require(:item).permit(assets_attributes: [:col1, :col2, :col3])
end
Then, make sure you use this private method when updating @item
:
@item.update_attributes item_params
ETA (based on your edit1): paperclip POSTs the actual file, not its attributes, so you would:
params.require(:item).permit(assets_attributes: [:asset])
For future reference you can find the parameters being passed to an action in the logs. It would look something like:
Parameters: {"utf8"=>"✓", "item"=>{"assets_attributes"=>[{"asset"=>#<ActionDispatch::Http::UploadedFile…>}]}
The logs will also include notice that any parameters have been excluded by strong params. This can be very helpful for determining which parameters need to be permitted.
I also want to strongly discourage adding all parameters to the permitted list. Strong parameters is motivated by serious security concerns, namely attackers being able to edit fields that they should not have access to. Basically, keep in mind that anyone with access to the web page will be able to post any value for any parameter in the permitted list.