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: true
as in the paperclip documentation:<%= form_for @product, :url => products_path, :html => { :multipart => true } do |f| %>
Because
Product
has_many :images
, in my form I havefields_for :images
instead offields_for :image
:<%= f.fields_for :images do |i| %> <%= i.file_field :image %> <% end %>
This
fields_for
doesn't show anything on the page unless in theProductsController#new
I build an image; does yourProduct.new
do 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