Custom return value for new / create ActiveRecord model
So I have a model (Photo), where when I call Photo.new @image => @image
/ Photo.create :image => @image
, I want my model to find an existing photo with the same image hash OR create a new Photo from @image. Assume I can't use Photo.find_or_initialize_by_hash
because I have a custom find function which finds close copies of images based on a soft image hash.
My first idea was to do
before_validation :check_duplicates, :on => :create
def check_duplicates
self = self.find_duplicate
end
Unfortunately, I realized you can't just redefine self in a model, so now I think the best approach is doing something along the lines of changing the return value from initialize to the duplicate.
Sort of like this, but it doesn't work (and I've heard horror stories about overriding initialize)
def initiali开发者_StackOverflowze(*params)
super(*params)
return self.find_duplicate || self
end
From what I gather your model structure looks something like this?
class Photo < ActiveRecord::Base
has_one :image
end
class Image < ActiveRecord::Base
belongs_to :photo
end
If so, you can simply do this:
class Photo < ActiveRecord::Base
has_one :image, :uniq => true
end
Or if :image is just an attribute of Photo your first idea was on track:
class Photo < ActiveRecord::Base
before_create :check_duplicate
private
def check_duplicate
Photo.where(:image => self.image).count == 0 # will be false if Photo is found
end
end
which will cancel the Photo from being created if #check_duplicate returns false (http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html)
Or simply
class Photo < ActiveRecord::Base
validates_uniqueness_of :image
end
精彩评论