使用Carrierwave与模型之间的一对多关系

时间:2012-10-31 23:16:10

标签: ruby-on-rails ruby-on-rails-3.2 carrierwave has-many

阶段

图像库应用程序。 我有两个模型HandcraftPhotos一个手工艺品可能有很多照片,假设我有这样的模型:

  • Handcraft(name:string)
  • Photo(filename:string, description:string, ...)

_form.html.erb手工艺品中,有:

<%= form_for @handcraft, html: {multipart: true} do |f| %>
  # ... other model fields

  <div class="field">
    <%= f.label :photo %><br />
    <%= f.file_field :photo %>
  </div>

  # ... submit button
<% end %>

handcraft.rb看起来像这样:

class Handcraft < ActiveRecord::Base
  attr_accessible :photo
  has_many :photos
  mount_uploader :photo, PhotoUploader
  # ... 
end

photo_uploader.rb

class PhotoUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :thumb do
    process :resize_to_limit => [100, 100]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

问题

当我提交表单时,会抛出此错误:

NoMethodError (undefined method `photo_will_change!' for #<Handcraft:0xb66de424>):

问题

在这种情况下我应该如何使用/配置Carrierwave?

1 个答案:

答案 0 :(得分:11)

您需要在将存储文件名的字段上安装上传器,因此您的模型应该看起来像

class Handcraft < ActiveRecord::Base
  attr_accessible :name
  has_many :photos
  # ... 
end

class Photo < ActiveRecord::Base
  attr_accessible :filename, :description
  mount_uploader :filename, PhotoUploader
  # ... 
end

然后看起来你将通过手工形式创建照片,你应该添加

accepts_nested_attributes_for :photos

在您的Handcraft班级

然后您的表单看起来像

<%= form_for @handcraft, html: {multipart: true} do |f| %>
  # ... other model fields

  <%= f.fields_for :photos do |photo| %>
    <%= photo.label :photo %><br />
    <%= photo.file_field :photo %>
  <% end %>

  # ... submit button
<% end %>

要显示照片字段的表单,您需要Handcraft个实例创建photos,这可以通过new HandcraftsController方法完成像那样:

def new
  @handcraft = Handcraft.new
  4.times { @handcraft.photos.build }
end

这将使您的表单中有4个(任意数字)字段可用,如果您希望用户以某种方式动态添加表单中的新照片,请查看nested_form