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

时间:2015-03-09 16:52:44

标签: ruby-on-rails ruby activerecord twitter rails-activerecord

我正在使用Twitter Gem从用户的时间线中提取和保存推文。在保存每个message之前,我想通过将新邮件tweet_id与已保存在tweet_id中的messages数组进行比较来检查此记录是否已存在。 D b。无论我尝试什么,我仍然看到重复的记录保存在@messages = Message.pull_tweets(@user) 表中。这是我得到的:

控制器电话:

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

" pull_tweets" 方法:

  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

" validate_uniqueness_of" 方法:

{{1}}

2 个答案:

答案 0 :(得分:1)

问题的最直接原因是tweets.each将返回tweets数组,因为它不是nil或false具有真值:你没有使用validate_uniqueness_of的结果{1}}方法。

您可能想要执行类似

之类的操作
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_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

答案 1 :(得分:0)

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

validates_uniqueness_of :tweet_id, scope: :user_id