kbeal
kbeal

Reputation: 118

Rails + carrierwave not creating conditional versions

I'm trying to set up conditional versions with carrierwave in my Rails app. I've implemented what seems to be an exact duplicate of the examples provided here.

The version is never created though unless my is_ipod? simply returns true. The code below is what I currently have and is not working. Notice the commented sections I've used to verify the image_type attribute is actually set correctly.

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

If is_ipod? looks like this:

def is_ipod? image
  true
end

the version is created as expected. What am I missing? Thanks!

UPDATE:

I've edited the is_ipod? method to look like this:

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

Which outputs this to the console:

/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

So the version is trying to be created three times, twice for temp files and once for the final file. The model attribute is only set for the final file. Is this related? Can anyone tell me how this is different than this example?

class MyUploader < CarrierWave::Uploader::Base

  version :monkey, :if => :is_monkey?

  protected

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

Here is my model class in case that helps:

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

Thanks!

Upvotes: 1

Views: 1429

Answers (3)

medBouzid
medBouzid

Reputation: 8392

I have the same issue this night and i'm doing some experimentation with it, finally i figured out, it seem that when your create a version for the first time (when you post your form), if you have this line :

model.image_type == 'iPod Screenshot'

this means that you should obligatory have a field in your form named image_type and the value for this field should be "iPod Screenshot"

CarrierWave verify the same thing when you show your image like article.image_url(:ipod_portrait_thumb) which means that you should have in your database a field named image_type with value "iPod Screenshot"

so if you have this line :

version :ipod_portrait_thumb, :if => :is_ipod?

you are telling CarrierWave to execute ipod_portrait_thumb function each time you Create or Show a record

in Case that your form don't contains the field image_type with value 'iPod Screenshot', for example because you set it in your model/controller, the way is to check another field to permit CarrierWave create your conditional version, so it's simple you can do something like this :

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

here when CarrierWave try to create version the first time it will check this another_field_...... , and when you have a page that show your record (product, article....) it verify model.image_type == 'iPod Screenshot' that is stored already in your database

Hope this help you :)

Upvotes: 1

focused
focused

Reputation: 364

I had a similar problem^ and I tried to create different sizes depending on model attribute. My solution is simple: just recreate versions after save.

app/uploaders/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

app/model/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

Upvotes: 2

kbeal
kbeal

Reputation: 118

It turns out this is happening because the AppImage model is a child of another model and is being added here on a nested form. For whatever reason child models don't have their attributes set by the time carrierwave processes versions.

I've verified this by adding carrierwave attachments to my parent model App. When the versions are processed for an App attachment, the attributes are set.

Maybe later I'll dig deeper to try and understand better (I'm pretty new to Rails), but for now I'm working around the issue by not having conditional versions.

Upvotes: 1

Related Questions