Heres what I\'m trying to accomplish:
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
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
where returns an empty ActiveRecord on finding no match.
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)
I believe the other answers are a bit dated. Here's how you should probably accomplish this for Rails 4
tag = Tag.first_or_initialize(:name => self.name, :user_id => current_user.id)
if !tag.new_record?
tag.id = self.id
tag.save
end
try this
def check_exists
tag = Tag.where(:name => self.name, :user_id => current_user.id).first
tag = Tag.new({:name => self.name, :user_id => current_user.id}) unless tag
end
use Tag.new
instead of Tag.create