Rails + carrierwave不创建条件版本

时间:2013-03-19 20:15:28

标签: ruby-on-rails ruby carrierwave

我正在尝试在我的Rails应用程序中使用carrierwave设置条件版本。我已经实现了与here提供的示例完全相同的内容。

除非is_ipod?只返回true,否则永远不会创建版本。下面的代码是我目前拥有的,不起作用。请注意,我用于验证image_type属性的注释部分实际上已正确设置。

version :ipod_portrait_thumb, :if => :is_ipod? do

  process resize_to_fit: [150,200]

end

def is_ipod? image
  model.image_type == 'iPod Screenshot'

  #if (model.image_type == "iPod Screenshot")
  #if (model.image_type!=nil)
    #puts "+++++"+model.image_type
  #  if (model.image_type=="iPod Screenshot")
      #puts "+++++++ I AM HERE"
  #   return true
  #  end
  #end
end

如果is_ipod?看起来像这样:

def is_ipod? image
  true
end

按预期创建版本。我错过了什么?谢谢!

更新

我已将is_ipod?方法编辑为如下所示:

def is_ipod? image     
  puts (image.path || "") + ': ' + ((model.image_type||"") == 'iPod Screenshot').to_s
  model.image_type == 'iPod Screenshot'
end

将其输出到控制台:

/public/uploads/tmp/20130325-1024-15906-5363/drawing.png: false
/public/uploads/tmp/20130325-1024-15906-5363/drawing.png: false
/public/uploads/app_image/image/59/drawing.png: true

因此版本试图创建三次,两次用于临时文件,一次用于最终文件。仅为最终文件设置model属性。这有关系吗?谁能告诉我这个例子与这个例子有何不同?

class MyUploader < CarrierWave::Uploader::Base

  version :monkey, :if => :is_monkey?

  protected

  def is_monkey? picture
    model.favorite_food == 'banana'
  end
end

这是我的模型类,如果有帮助:

class AppImage < ActiveRecord::Base
  attr_accessible :app_id, :image, :image_type, :image_cache
  belongs_to :app

  mount_uploader :image, AppImageUploader

  validates :image_type, presence: true
  validates :image, presence: true
end

谢谢!

3 个答案:

答案 0 :(得分:1)

事实证明这种情况正在发生,因为AppImage模型是另一个模型的子模型,并且是在嵌套表单上添加的。无论出于何种原因,子模型都没有在载波处理版本时设置其属性。

我已经通过将carrierwave附件添加到我的父模型App来验证了这一点。处理App附件的版本时,将设置属性。

也许以后我会更深入地尝试更好地理解(我对Rails很新),但是现在我正在通过没有条件版本解决这个问题。

答案 1 :(得分:1)

我有类似的问题^我尝试根据模型属性创建不同的大小。我的解决方案很简单:只需在保存后重新创建版本。

应用程序/上传/ project_item_picture_uploader.rb

class ProjectItemPictureUploader < CarrierWave::Uploader::Base

  ...

  version :preview do
    process dynamic_process: true
  end

  protected

  def dynamic_process(*args)
    resize_to_fill *(model.get_size) if model.persisted?
  end

end

应用程序/模型/ project_item.rb

class ProjectItem < ActiveRecord::Base
  mount_uploader :picture, ProjectItemPictureUploader
  validates_presence_of :picture

  def get_size
    double ? [168, 57] : [76, 57]
  end

  after_save :recreate_delayed_versions!
  def recreate_delayed_versions!
    picture.recreate_versions!
  end
end

答案 2 :(得分:1)

今晚我有同样的问题,我正在做一些实验,最后我想通了,看来当你第一次创建一个版本时(当你发布你的表单时),如果你有这条线:

model.image_type == 'iPod Screenshot'

这意味着您必须在您的表单中有一个名为image_type的字段,该字段的值应为“iPod Screenshot”

当你展示像article.image_url(:ipod_portrait_thumb)这样的图像时,CarrierWave验证同样的事情,这意味着你的数据库中应该有一个名为image_type的字段,其值为“iPod Screenshot”

所以,如果你有这一行:

version :ipod_portrait_thumb, :if => :is_ipod?

每次创建或显示记录时,您都告诉CarrierWave执行ipod_portrait_thumb功能

如果您的表单不包含值为“iPod屏幕截图”的field image_type,例如因为您在模型/控制器中设置它,那么方法是检查另一个字段以允许CarrierWave创建条件版本,所以很简单,你可以做这样的事情:

model.image_type == 'iPod Screenshot' || another_field_in_my_form_help_you_to_know_type_is_ipode == "something" # or just .present? rather than == "something" switch your case

当CarrierWave第一次尝试创建版本时,它会检查另一个_field_......,当你有一个页面显示你的记录(产品,文章......)时,它会验证{{1}已存储在数据库中的

希望这可以帮助你:)