I have 3 models in my rails app
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
the Contact consists of the voter_id and a survey_id. The Logic of my app is that a there can only be one contact for a voter in any given survey.
right now I am using the following code to enforce this logic. I query the contacts table for records matching the given voter_id and survey_id. if does not exist then it is created. otherwise it does nothing.
if !Contact.exists?(:survey_id => survey, :voter_id => voter) c = Contact.new c.survey_id = survey c.voter_id = voter c.save end
Obviously this requires a select and a insert query to create 1 potential contact. When I am adding potentially thousands of contacts at once.
Right now I'm using Resque to allow this run in the background and away from the ui thread. What can I do to speed this up, and make it more efficient?
There are three ways you can perform an “insert if not exists” query in MySQL: Using the INSERT IGNORE statement. Using the ON DUPLICATE KEY UPDATE clause. Or using the REPLACE statement.
The clause “if not exists” is used for the creation of tables and is very useful for avoiding the error “table already exists”, as it will not create a table if, in the database, any table is already available by the name of the new table.
You can do the following:
Contact.where(survey_id: survey,voter_id: voter).first_or_create
You should add first a database index to force this condition at the lowest level as possible:
add_index :contacts, [:voter_id, :survey_id], unique: true
Then you should add an uniqueness validation at an ActiveRecord level:
validates_uniqueness_of :voter_id, scope: [:survey_id]
Then contact.save
will return false
if a contact exists for a specified voter and survey.
UPDATE: If you create the index, then the uniqueness validation will run pretty fast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With