Hoan Dang
Hoan Dang

Reputation: 2280

Elegant solution to avoid duplicates when validating a unique field?

I did successfully validate duplicated url straight in the model. The code below shows that the validation works well when the user creates a new bookmark.

validate :url_cannot_be_duplicated_per_user

def url_cannot_be_duplicated_per_user
  current_user = User.find(self.user_id)
  if current_user.bookmarks.any?{|b| b.url.eql? self.url }
    errors.add(:url, "already added")
  end
end

But the problem is the validation prevents editing a bookmark because when editing it bascially same bookmark, it will go through the model again and catch the duplication. So with that code the update action never happen.

Any idea how to fix it?

PS: I did put a block if else in the controller to check url first before submitting to model. The code goes messy although the validation worked pretty much correctly.

My controller

if duplicated? params[:bookmark][:url]
  flash[:error] = 'This bookmark already added'
  @bookmark = current_user.bookmarks.build(params[:bookmark])
  render 'new'
else

Upvotes: 1

Views: 841

Answers (1)

PinnyM
PinnyM

Reputation: 35531

You can validate uniqueness with scope:

class Bookmark < ActiveRecord::Base
  validates :url, :uniqueness => {:scope => :user_id}
end

Upvotes: 2

Related Questions