簡體   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