I have two associated models in my Rails 4 app: product.rb and image.rb. The Image model allows attached files using the Paperclip gem.
Images belong_to a Product, and a product has_many Images.
I would like to use the Product's new view to create and attach an image when I create a product. Each time I try, the parameters associated with the Paperclip image do not get saved, and end up nil.
Here are the models:
Product.rb
class Product < ActiveRecord::Base
validates :name, :part_number, presence: true
has_many :images, dependent: :destroy
belongs_to :category
accepts_nested_attributes_for :images, allow_destroy: true
end
Image.rb
class Image < ActiveRecord::Base
belongs_to :product
has_attached_file :image
end
Looking through past Stack Overflow questions I've found some relevant questions and answers, but none that seem to help my particular situation. So far I'm able to submit the file with the correct attributes, but it doesn't save them to the database.
ProductsController#create
def create
@product = Product.new(product_params)
end
def product_params
params.require(:product).permit(:name,
:category_id,
:part_number,
images_attributes: [:image])
end
ProductsController#new
def new
@product = Product.new
@categories = # irrelevant to question
end
products/new.html.haml
= form_for @product, :html =>
= f.label :name
= f.text_field :name
= f.label :part_number
= f.text_field :part_number
= f.label :category_id
= f.select :category_id, @ca
= f.fields_for :image do |ff|
= ff.label :image
= ff.file_field :image
= f.submit('Create Product')
Looking at the parameters I can tell that the correct attributes are being passed on:
Example parameters:
{"utf8"=>"✓",
"authenticity_token"=>"jGNy/TasHzP0EcWDFzZ3XH5/fpxb6vD+ncQ2PZSQ3/I=",
"product"=>{"name"=>"bar",
"part_number"=>"foo",
"category_id"=>"30",
"image"=>{
"image"=>#<ActionDispatch::Http::UploadedFile:0x007fc82f58e0e0
@tempfile=#<Tempfile:/var/folders/04/23d9grkj5fv3wkj2t8858kx40000gn/T/RackMultipart20131029-64949-1ldkz4g>,
@original_filename="FPE230_b.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"product[image][image]\"; filename=\"FPE230_b.jpg\"\r\nContent-Type: image/jpeg\r\n">}},
"commit"=>"Create Product"}
However, the image is not actually being saved to the database. How can I rectify this?
EDIT
Looking more closely at the logs, I see that I'm getting an "unpermitted parameters: image" error. This is even after adding images_attributes: [:image] to my product_params method.
I was able to get a setup similar to yours working with the following changes:
In ProductsController#create, instead of building the image separately, let the nested attributes handle it and just do:
@product = Product.new(product_params)
And allow the nested parameters (I figured out the image_attributes: [:image] from this question):
def product_params
params.require(:product).permit(:name, :part_number, images_attributes: [:image])
end
This is what my parameters look like in the logs for a create request:
{
"utf8"=>"✓",
"authenticity_token"=>"7EsPTNXu127itgp4fbohu672/L4XnSwLEkrqUGec3pY=",
"product"=>{
"name"=>"whatever",
"part_number"=>"12345",
"images_attributes"=>{
"0"=>{
"image"=>#<ActionDispatch::Http::UploadedFile:0x007feb0c183b08
@tempfile=#<Tempfile:/var/folders/6k/16k80dds0ddd6mhvs5zryh3r0000gn/T/RackMultipart20131031-51205-emaijs>,
@original_filename="some-image.png",
@content_type="image/png",
@headers="Content-Disposition: form-data; name=\"product[images_attributes][0][image]\"; filename=\"ponysay.png\"\r\nContent-Type: image/png\r\n">
}
}
},
"commit"=>"Create"}
And I see an insert into products and an insert into images.
If that doesn't work, could you post your ProductsController#new and your new product form?
EDIT AFTER YOUR EDIT:
I have 3 different things in my app/views/products/new.html.erb and ProductsController#new that might be affecting your results:
In the
form_for, I havemultipart: trueas in the paperclip documentation:<%= form_for @product, :url => products_path, :html => { :multipart => true } do |f| %>Because
Producthas_many :images, in my form I havefields_for :imagesinstead offields_for :image:<%= f.fields_for :images do |i| %> <%= i.file_field :image %> <% end %>This
fields_fordoesn't show anything on the page unless in theProductsController#newI build an image; does yourProduct.newdo this by any chance?def new @product = Product.new @product.images.build end
Are there any particular reasons for these differences you have? Does your code work if you change it to match mine?
来源:https://stackoverflow.com/questions/19664744/cant-save-image-attributes-with-paperclip-in-rails-4