[英]check if record exists before saving to db - Rails, Twitter, ActiveRecord
I am using a Twitter Gem to pull and save Tweets from user's timeline. 我正在使用Twitter Gem从用户的时间轴中提取并保存Tweets。 Before saving each
message
, I want to check if this record already exists by comparing the new message's tweet_id
to the array of tweet_id
's already saved in the db. 节约每一之前
message
,我要检查,如果这个记录已经被新的消息的比较存在tweet_id
到的阵列tweet_id
的已经保存在数据库中。 No matter what I try, I am still seeing duplicated records being saved in the messages
table. 无论我尝试什么,我仍然会看到重复的记录被保存在
messages
表中。 Here is what I got: 这是我得到的:
Controller call: 控制器调用:
@messages = Message.pull_tweets(@user)
"pull_tweets" method: “ 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" method: “ 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
The most direct cause of your problem is that tweets.each
will return the tweets
array, which since it is not nil or false has a truthy value: you're not using the result of your validate_uniqueness_of
method. 问题的最直接原因是
tweets.each
将返回tweets
数组,由于它不是nil或false,因此具有真实值:您没有使用validate_uniqueness_of
方法的结果。
You instead would want to either do something like 相反,您可能想做类似的事情
tweets.all? { |tweet| validate_uniqueness_of(user,tweet) }
which returns true only if all the tweets meet your test, or more likey to be what you want 仅当所有推文都通过您的测试时才返回true,或更可能是您想要的
if tweets
tweets = tweets.select { |tweet| validate_uniqueness_of(user,tweet) }
tweets.each { |tweet| user.messages.create!(tweet_id: tweet.id ... }
end
This would however be rather non idiomatic code. 但是,这将是相当惯用的代码。 You would usually create a validation on your tweet class and add a unique index on the
tweet_id
column - a uniqueness validation should always be backed up by a unique index or you run the risk of rice conditions. 通常,您将在tweet类上创建一个验证,并在
tweet_id
列上添加一个唯一索引-唯一性验证应始终由唯一索引来备份,否则您将面临大米状况的风险。
The validation side of things would look like 验证方面看起来像
class Message < ActiveRecord::Base
validate_uniqueness_of :tweet_id, scope: :user_id #assuming that message belongs_to :user
end
You can either keep using create! 您可以继续使用create! and rescue the validation exception that will be thrown or switch to
create
which returns true/false depending on what happened. 并挽救将抛出的验证异常或切换到
create
该异常,根据发生的情况返回true / false。 In both cases ActiveRecord::RecordNotUnique
will be raised if a duplicate slips past the validation 在这两种情况下,如果重复项超出验证范围,则会引发
ActiveRecord::RecordNotUnique
您还可以根据:scope参数来验证tweet_id是否唯一:
validates_uniqueness_of :tweet_id, scope: :user_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.