How to check if a record exists before creating a new one in rails3?

You're going to find it hard to to this from within the Tag model. It seems like what you want is to update the Post using nested attributes, like so:

post = Post.create
post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})

This is actually pretty simple to do by using a virtual attribute setter method:

class Post < AR::Base
  has_many :tags

  def tags_attributes=(hash)
    hash.each do |sequence,tag_values|
      tags <<  Tag.find_or_create_by_name_and_user_id(tag_values[:name],\
        tag_values[:user_id])
    end
  end

> post = Post.create
> post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
> Tag.count # => 1
# updating again does not add dups
> post.update_attributes(:tags_attributes=>{"0"=>{:name=>"fish",:user_id=>"37"}})
> Tag.count # => 1

There's a find_or_create_by_ function built right in to Rails

# No 'Summer' tag exists
Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")

# Now the 'Summer' tag does exist
Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")

http://api.rubyonrails.org/classes/ActiveRecord/Base.html (under Dynamic attribute-based finders)


You want to use the magic method find_or_create_by

def check_exists
    tag = Tag.find_or_create_by_name_and_user_id(:name => self.name, :user_id => current_user.id)
end

Check out the ActiveRecord::Base docs for more info