【问题标题】:check if record exists before saving to db - Rails, Twitter, ActiveRecord在保存到数据库之前检查记录是否存在 - Rails、Twitter、ActiveRecord
【发布时间】:2015-05-10 22:28:43
【问题描述】:

我正在使用Twitter Gem 从用户的时间线中提取和保存推文。在保存每个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

【问题讨论】:

  • 您可以在消息模型中简单地使用validates :tweet_id, uniqueness: true
  • 好像你永远不知道 ActiveRecord 的 exists? 方法。

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


【解决方案1】:

问题的最直接原因是 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_id 列上添加一个唯一索引 - 唯一性验证应始终由唯一索引支持,否则您将面临大米条件的风险。

事物的验证方面看起来像

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

您可以继续使用 create!并拯救将被抛出的验证异常或切换到create,根据发生的情况返回真/假。在这两种情况下,如果重复通过验证,将引发 ActiveRecord::RecordNotUnique

【讨论】:

  • 当然! tweets.each 将返回 truetruthy,因此通过该部分的所有内容都将被忽略。非常感谢!
【解决方案2】:

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

validates_uniqueness_of :tweet_id, scope: :user_id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    相关资源
    最近更新 更多