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

时间:2012-06-20 14:40:39

标签: ruby-on-rails ruby carrierwave

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

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

  accepts_nested_attributes_for :holiday_image, allow_destroy: true, :reject_if => lambda { |a| a[:title].blank? }

我不明白为什么我需要在accept_nested_attributes_for协会上采取措施:

:reject_if => lambda { |a| a[:title].blank? }

如果我删除它: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

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

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

  mount_uploader :image, ImageUploader
end

在我的_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 %>

再次感谢您的耐心等待。

1 个答案:

答案 0 :(得分:1)

accepts_nested_attributes_for通常用于在批量分配期间构建子项(创建新记录时,构建任何关联模型)。例如,如果您有User has_many UserPhotos之类的模型,则可以在创建UserPhotos期间使用多个User,并将它们全部放入建立在User创造。

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

有几种方法可以解决这个问题,但这里有一些你应该知道的基本信息:

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

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

  3. 如果您希望以嵌套形式接受多个图片,请参阅使用accept_nested_attributes_for的{​​{3}}。