繁体   English   中英

在保存到数据库之前检查记录是否存在-Rails,Twitter,ActiveRecord

[英]check if record exists before saving to db - Rails, Twitter, ActiveRecord

我正在使用Twitter Gem从用户的时间轴中提取并保存Tweets。 节约每一之前message ,我要检查,如果这个记录已经被新的消息的比较存在tweet_id到的阵列tweet_id的已经保存在数据库中。 无论我尝试什么,我仍然会看到重复的记录被保存在messages表中。 这是我得到的:

控制器调用:

@messages = Message.pull_tweets(@user)

“ pull_tweets”方法:

def self.pull_tweets(user)

    tweets = $twitter.home_timeline  # API call to pull all tweets from the timeline

    if tweets && tweets.each { |tweet| validate_uniqueness_of(user,tweet) }
      tweets.each { |tweet| user.messages.create!(tweet_id: tweet.id ... }
      ...
    else
      ... 
    end
  end

“ validate_uniqueness_of”方法:

  def self.validate_uniqueness_of(user,tweet)
    if user.messages.pluck(:tweet_id).exclude?(tweet.id.to_s)
      return true
    else
      return false
    end
  end

问题的最直接原因是tweets.each将返回tweets数组,由于它不是nil或false,因此具有真实值:您没有使用validate_uniqueness_of方法的结果。

相反,您可能想做类似的事情

tweets.all? { |tweet| validate_uniqueness_of(user,tweet) }

仅当所有推文都通过您的测试时才返回true,或更可能是您想要的

if tweets
  tweets = tweets.select { |tweet| validate_uniqueness_of(user,tweet) }
  tweets.each { |tweet| user.messages.create!(tweet_id: tweet.id ... } 
end 

但是,这将是相当惯用的代码。 通常,您将在tweet类上创建一个验证,并在tweet_id列上添加一个唯一索引-唯一性验证应始终由唯一索引来备份,否则您将面临大米状况的风险。

验证方面看起来像

class Message < ActiveRecord::Base
  validate_uniqueness_of :tweet_id, scope: :user_id #assuming that message belongs_to :user
end

您可以继续使用create! 并挽救将抛出的验证异常或切换到create该异常,根据发生的情况返回true / false。 在这两种情况下,如果重复项超出验证范围,则会引发ActiveRecord::RecordNotUnique

您还可以根据:scope参数来验证tweet_id是否唯一:

validates_uniqueness_of :tweet_id, scope: :user_id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM