Reputation: 118
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
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
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
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