【问题标题】:Can't Save Image Attributes with Paperclip in Rails 4无法在 Rails 4 中使用回形针保存图像属性
【发布时间】:2013-10-29 17:05:39
【问题描述】:

我的 Rails 4 应用中有两个关联模型:product.rbimage.rb。 Image 模型允许使用 Paperclip gem 附加文件。

图片belong_to一个产品,一个产品has_many图片。

我想在创建产品时使用产品的new 视图来创建和附加图像。每次我尝试时,与回形针图像相关的参数都不会被保存,最终是nil

以下是模型:

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

查看过去的 Stack Overflow 问题,我找到了一些相关的问题和答案,但似乎没有一个对我的特殊情况有帮助。到目前为止,我能够提交具有正确属性的文件,但它不会将它们保存到数据库中。

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')

查看参数我可以看出正在传递正确的属性:

示例参数:

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

但是,图像实际上并未保存到数据库中。我该如何纠正这个问题?

编辑

仔细查看日志,我发现我收到了“未经许可的参数:图像”错误。即使在我的 product_params 方法中添加了 images_attributes: [:image] 之后也是如此。

【问题讨论】:

  • 请问你用的是什么版本的回形针?
  • 最新:gem "paperclip", :git =&gt; "git://github.com/thoughtbot/paperclip.git"
  • 为了将来参考,今天在 github.com/thoughtbot/paperclip 的 HEAD 的提交是 8e900b2a139deff9114efe84e6327235c92e6103。你能确认这是你正在使用的提交吗?它刚刚在 2 天前更新,并且更改相当频繁。谢谢!
  • 好点。我在一两次提交后落后于 HEAD。在诊断问题时,出于稳定性考虑,我将使用 3.5.2。

标签: ruby-on-rails-4 paperclip strong-parameters


【解决方案1】:

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

ProductsController#create中,不要单独构建图像,而是让嵌套属性处理它,然后做:

@product = Product.new(product_params)

并允许嵌套参数(我从this question 中找出了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"}

我看到一个插入到products 和一个插入到images

如果这不起作用,您能否发布您的ProductsController#new 和您的新产品表单?

编辑后编辑:

我的 app/views/products/new.html.erbProductsController#new 中有 3 个不同的内容可能会影响您的结果:

  1. form_for 中,我有multipart: truepaperclip documentation 一样:

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

    <%= f.fields_for :images do |i| %>
      <%= i.file_field :image %>
    <% end %>
    
  3. 这个fields_for 不会在页面上显示任何内容,除非我在ProductsController#new 中构建了一个图像;你的Product.new 有没有机会这样做?

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

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

【讨论】:

  • 还是不行。我添加了new 方法和表单,冒着被一大堆文字吓跑的风险。
  • 有时需要一堵文字墙 :)
  • fields_for 中的复数images!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多