ruby-on-rails - 如果记录不存在则创建

标签 ruby-on-rails ruby-on-rails-4

我的Rails应用中有3个模型

class Contact < ActiveRecord::Base
  belongs_to :survey, counter_cache: :contact_count
  belongs_to :voter
  has_many :contact_attempts
end

class Survey < ActiveRecord::Base
  has_many :questions
  has_many :contacts
end

class Voter < ActiveRecord::Base
  has_many :contacts
end

联系人由选民ID和Survey_ID组成。我的应用程序的逻辑是,在任何给定的调查中,一个选民只能有一个联系人。

现在,我正在使用以下代码来强制执行此逻辑。我在联系人表中查询与给定的表决者ID和Survey_id匹配的记录。如果不存在,则创建它。否则它什么都不做。
if !Contact.exists?(:survey_id => survey, :voter_id => voter)
   c = Contact.new
   c.survey_id = survey
   c.voter_id = voter
   c.save
end

显然,这需要选择和插入查询才能创建1个潜在联系人。当我一次添加潜在的数千个联系人时。

现在,我正在使用Resque允许此操作在后台运行,并且远离ui线程。我怎样做才能加快速度并提高效率?

最佳答案

您应该首先添加一个数据库索引,以使此条件处于最低级别:

add_index :contacts, [:voter_id, :survey_id], unique: true

然后,您应该在ActiveRecord级别添加唯一性验证:
validates_uniqueness_of :voter_id, scope: [:survey_id]

如果指定选民和调查存在联系人,则contact.save将返回false

更新:如果创建索引,则唯一性验证将运行得非常快。

关于ruby-on-rails - 如果记录不存在则创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21718351/

相关文章:

ruby-on-rails - 使用装饰器,(rails) 无法推断 ActiveRecord::Base 的装饰器

ruby-on-rails - 为什么 ruby​​-debug 说 'Saved frames may be incomplete'

ruby-on-rails - 守护进程自动终止

ruby-on-rails - rails 4 升级后 Controller rspec 中的 ActionController::UnknownFormat

ruby-on-rails - 跳过rails counter_cache更新

ruby-on-rails - 将ActiveRecord对象与Rspec进行比较

ruby-on-rails - 无法在任何来源中找到 json-1.8.1 (Bundler::GemNotFound)

javascript - Twitter-Typeahead 不提供建议

ruby-on-rails - 在 Rails 4 中默认禁用强参数

ruby - Spree 中的 NameError::Products#show