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

后端 未结 7 1407
悲哀的现实
悲哀的现实 2021-02-03 14:36

Heres what I\'m trying to accomplish:

  • I have a tagging system in place.
  • Tags are created, when Posts are created (posts has_many :tags, :through => :tag
相关标签:
7条回答
  • 2021-02-03 15:09

    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
    
    0 讨论(0)
  • 2021-02-03 15:09

    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

    0 讨论(0)
  • 2021-02-03 15:09

    where returns an empty ActiveRecord on finding no match.

    0 讨论(0)
  • 2021-02-03 15:12

    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)

    0 讨论(0)
  • 2021-02-03 15:16

    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
    
    0 讨论(0)
  • 2021-02-03 15:21

    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

    0 讨论(0)
提交回复
热议问题