4

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.

4

1 回答 1

3

通过以下更改,我能够获得类似于您的设置:

ProductsController#create中,不是单独构建图像,而是让嵌套属性处理它并执行以下操作:

@product = Product.new(product_params)

并允许嵌套参数(我image_attributes: [:image]这个问题中找到了):

def product_params
  params.require(:product).permit(:name, :part_number, images_attributes: [:image])
end

create这是我的参数在请求日志中的样子:

{
   "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"}

我看到一个 insert intoproducts和一个 insert into images

如果这不起作用,您可以发布您ProductsController#new和您的新产品表格吗?

编辑后编辑:

我有 3 个不同的东西,app/views/products/new.html.erbProductsController#new可能会影响你的结果:

  1. 在 中form_for,我multipart: true回形针文档中拥有:

    <%= form_for @product, :url => products_path, :html => { :multipart => true } do |f| %>
    
  2. 因为Product has_many :images,在我的表格中,我有fields_for :images而不是fields_for :image

    <%= f.fields_for :images do |i| %>
      <%= i.file_field :image %>
    <% end %>
    
  3. 除非在我构建图像中,否则这fields_for不会在页面上显示任何内容;ProductsController#newProduct.new会这样做吗?

    def new
      @product = Product.new
      @product.images.build
    end
    

你有这些差异有什么特别的原因吗?如果您更改代码以匹配我的代码,您的代码是否有效?

于 2013-10-31T23:31:01.880 回答