Can't Save Image Attributes with Paperclip in Rails 4

社会主义新天地 提交于 2019-12-07 08:27:08

问题


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.


回答1:


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:

  1. In the form_for, I have multipart: true as in the paperclip documentation:

    <%= form_for @product, :url => products_path, :html => { :multipart => true } do |f| %>
    
  2. Because Product has_many :images, in my form I have fields_for :images instead of fields_for :image:

    <%= f.fields_for :images do |i| %>
      <%= i.file_field :image %>
    <% end %>
    
  3. This fields_for doesn't show anything on the page unless in the ProductsController#new I build an image; does your Product.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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!