Search code examples
ruby-on-railspaperclipnested-sets

default pic when using multiple nested images on paperclip


I am using Paperclip to upload multiple item images. I followed some of this tutorial http://sleekd.com/general/adding-multiple-images-to-a-rails-model-with-paperclip/ My models are:

Item.rb

has_many :item_images, :dependent => :destroy
accepts_nested_attributes_for :item_images, :reject_if => lambda { |l| l['item_image'].nil? }

ItemImage.rb

class ItemImage < ActiveRecord::Base
 belongs_to :item
 belongs_to :user
 #for image. Paperclip     following Bootstrap sizes.
 has_attached_file :image,
                :styles => { :large => ["330x230>",:png], :medium => ["210x150>",:png], :small => ["90x90>",:png], :thumb => ["32x32>", :png] },
                :default_url => '/images/missing_image_:style.png',
                :storage => :s3,
                :bucket => 'iscomp',
                :s3_credentials => "#{RAILS_ROOT}/config/amazon_s3.yml",
                :path => "iscomp/:attachment/:style/:id.:extension"
 validates_attachment_presence :image
 validates_attachment_size :image, :less_than => 5.megabytes
end 

My issue is that because the images are stored on a second model, I am not able to access a default blank image when there are no images/records on the @item.item_image. If I had used paperclip directly on @item, Paperclip will return default image for me.

What's the best way of doing this if I do not want to keep adding in if/unless statements whenever I call for a thumbnail?


Solution

  • You can solve this issue by:

    Adding an itemimage_count in your migration

      def self.up  
       add_column :item, :itemimage_count, :integer, :default => 0
    
     Item.reset_column_information  
       Item.all.each do |item|  
         item.update_attribute :itemimage_count, item.itemimages.length  
       end  
     end  
    
     def self.down  
       remove_column :item, :itemimage_count  
     end
    end
    

    This will then associate a number of ItemImages with each Item. You can than access this counter in your views, controllers and models.

    If you want to get pretty with it you can simply set a scope condition in your model.

    Item.rb

    scope :list, :conditions => ["itemimages_count >= 0"]
    

    Item_controller

    @itemimages = Item.list
    

    I would personally make a partial in your views with 1 set of if else statements, whenever you want to display the images simply call out to the partial.

    if Item.itemimages_count == 0
        #show this image
    end
     #code that displays an Item's image
        #show the image in itemimages
    

    I hope this helps someone.