如果照片:标题包含在表单中,CarrierWave和嵌套表单将保存空图像对象

Was*_*per 5 ruby ruby-on-rails carrierwave

我正在处理有关处理嵌套表单数据的一些建议,我会非常感谢任何见解.

问题是我不能100%确定为什么我需要在我的模型中使用以下代码

  accepts_nested_attributes_for :holiday_image, allow_destroy: true, :reject_if => lambda { |a| a[:title].blank? }
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我需要在accept_nested_attributes_for关联上进行操作:

:reject_if => lambda { |a| a[:title].blank? }
Run Code Online (Sandbox Code Playgroud)

如果我删除它:reject_if lambda,它将在数据库中保存一个空白的假日照片对象.我推测是因为它将表单中的:title字段作为空字符串?

我想我的问题是,如果我想扩展我的HolidayImage模型以包含更多字符串(如描述,注释),我是否正确执行此操作或在嵌套表单中有更好的方法吗?

对不起如果我不能更简洁.

我简单的假期应用.

# holiday.rb 
class Holiday < ActiveRecord::Base
  has_many :holiday_image
  accepts_nested_attributes_for :holiday_image, allow_destroy: true, :reject_if => lambda { |a| a[:title].blank? }

  attr_accessible :name, :content, :holiday_image_attributes

end
Run Code Online (Sandbox Code Playgroud)

我正在使用CarrierWave进行图片上传.

# holiday_image.rb 
class HolidayImage < ActiveRecord::Base
  belongs_to :holiday
  attr_accessible :holiday_id, :image, :title

  mount_uploader :image, ImageUploader
end
Run Code Online (Sandbox Code Playgroud)

在我的_form部分里面有一个field_for块

<h3>Photo gallery</h3>
<%= f.fields_for :holiday_image do |holiday_image| %>
<% if holiday_image.object.new_record? %>

  <%= holiday_image.label :title, "Image Title" %>
  <%= holiday_image.text_field :title %>
  <%= holiday_image.file_field :image %>

<% else %>

  Title: <%= holiday_image.object.title %>
  <%= image_tag(holiday_image.object.image.url(:thumb)) %>
  Tick to delete: <%= holiday_image.check_box :_destroy %>

<% end %>
Run Code Online (Sandbox Code Playgroud)

再次感谢您的耐心等待.

小智 1

accepts_nested_attributes_for通常用于在批量分配期间构建子级(创建新记录、构建任何关联模型时)。例如,如果您有一个类似于Userwhich 的模型has_many UserPhotos,则可以UserPhotos在创建 a 期间采用多个模型User,并将它们全部构建在User创建过程中。

我不认为您需要处理嵌套属性,因为您只是ImageUploader在单个模型 ( HolidayImage) 上安装单个图像 ( )。这为模型提供了HolidayImage一个字段 ,:imageCarrierWave 将使用该字段来挂载 的实例ImageUploader

有几种方法可以解决这个问题,但以下是您应该了解的一些基本信息:

  1. 您可以使用validates_presence_of :image它来确保:image存在。这是有效的,因为安装的上传器实现了present?验证 API 使用的方法(请参阅 Carrier Wave Wiki 上的使用 ActiveRecord 验证上传)。这样您就不必测试标题是否已设置,而是可以在允许创建模型之前测试图像是否已上传。当然,您应该根据需要处理失败的验证。

  2. 您可以添加一个before_save执行任何您想要的操作,它可以询问 CarrierWave 图像是否存在或刚刚上传。在您的情况下,您可以分别调用image.present?image_changed?来在您的模型中对此进行测试HolidayImage。有关示例,请参阅此 CarrierWave 操作方法。

  3. 如果您想以嵌套形式接受多个图像,请参阅此 CarrierWave 如何使用accept_nested_attributes_for