我正在使用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}}
答案 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