Skip to content

Instantly share code, notes, and snippets.

@rigelstpierre
Created December 12, 2012 21:21
Show Gist options
  • Save rigelstpierre/4271755 to your computer and use it in GitHub Desktop.
Save rigelstpierre/4271755 to your computer and use it in GitHub Desktop.
class Photo < ActiveRecord::Base
belongs_to :listing, :counter_cache => true
scope :by_landlord, lambda {|landlord_id| joins(:listing).where('landlord_id = ?', landlord_id)}
default_scope order('"photos"."index" ASC')
attr_accessible :index, :image, :image_url, :image_processing
attr_accessor :is_pre_listing
validates_presence_of :listing_id, :unless => :is_pre_listing
validate :validate_listing_photo_count, :unless => :is_pre_listing
def validate_listing_photo_count
errors[:base] << "This listing already has 9 photos" if listing.photos.length >= 9
end
after_save :cleanup_photo_indices, :unless => :is_pre_listing
after_destroy :cleanup_photo_indices, :unless => :is_pre_listing
def cleanup_photo_indices
listing.photos.order(:index, 'created_at DESC').each_with_index do |p, i|
p.update_column(:index, i)
end
end
def image_url_for(size)
"http://s3.amazonaws.com/#{S3_CREDENTIALS[:bucket]}/photos/#{id}/#{size}/#{image_file_name}"
end
# How to implement on Heroku with processing in the background
# http://madeofcode.com/posts/42-paperclip-s3-delayed-job-in-rails
has_attached_file :image,
:styles => {
:large => "640x960>",
:small => "320x480>",
:thumbnail => "160x240>",
:feed => "550x380>"
},
:convert_options => { :all => '-auto-orient' },
:storage => :s3,
:s3_credentials => S3_CREDENTIALS,
:s3_permissions => :public_read,
:path => "photos/:id/:style/:filename"
validates_attachment_presence :image
before_validation :download_image
def download_image
if self.image_url.present? && new_record?
puts "DOWNLOADING IMAGE", id
self.image = URI.parse(image_url)
end
true
end
# generate styles (downloads original first)
def regenerate_styles!
self.image.reprocess!
self.update_column(:image_processing, false)
end
# cancel post-processing now, and set flag...
before_image_post_process do |photo|
if !photo.image_processing && photo.image_changed?
photo.image_processing = true
false # halts processing
end
end
# call method from after_save that will be processed in the background
after_save do
if self.image_processing && self.image_changed?
self.delay.regenerate_styles!
end
end
def image_changed?
image_file_size_changed? ||
image_file_name_changed? ||
image_content_type_changed? ||
image_url_changed?
end
def calculate_dimensions
self.image.reprocess!
self.save
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment