Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Sunday, July 24, 2016

How do you validate uniqueness of a pair of ids in Ruby on Rails?

How do you validate uniqueness of a pair of ids in Ruby on Rails?


Suppose the following DB migration in Ruby:

      create_table :question_votes do |t|        t.integer :user_id        t.integer :question_id        t.integer :vote          t.timestamps      end  

Suppose further that I wish the rows in the DB contain unique (user_id, question_id) pairs. What is the right dust to put in the model to accomplish that?

validates_uniqueness_of :user_id, :question_id
seems to simply make rows unique by user id, and unique by question id, instead of unique by the pair.

Answer by Demi for How do you validate uniqueness of a pair of ids in Ruby on Rails?


validates_uniqueness_of :user_id, :scope => [:question_id]  

if you needed to include another column (or more), you can add that to the scope as well. Example:

validates_uniqueness_of :user_id, :scope => [:question_id, :some_third_column]  

Answer by eggdrop for How do you validate uniqueness of a pair of ids in Ruby on Rails?


Except for writing your own validate method, the best you could do with validates_uniqueness_of is this:

validates_uniqueness_of :user_id, :scope => "question_id"  

This will check that the user_id is unique within all rows with the same question_id as the record you are attempting to insert.

But that's not what you want.

I believe you're looking for the combination of :user_id and :question_id to be unique across the database.

In that case you need to do two things:

  1. Write your own validate method.
  2. Create a constraint in the database because there's still a chance that your app will process two records at the same time.

Answer by pakeha for How do you validate uniqueness of a pair of ids in Ruby on Rails?


If using mysql, you can do it in the database using a unique index. It's something like:

add_index :question_votes, [:question_id, :user_id], :unique => true  

This is going to raise an exception when you try to save a doubled-up combination of question_id/user_id, so you'll have to experiment and figure out which exception to catch and handle.

Answer by Jonathan Lin for How do you validate uniqueness of a pair of ids in Ruby on Rails?


From RailsGuides. validates works too:

class QuestionVote < ActiveRecord::Base    validates :user_id, :uniqueness => { :scope => :question_id }  end  

Answer by dpedoneze for How do you validate uniqueness of a pair of ids in Ruby on Rails?


The best way is to use both, since rails isn't 100% reliable when uniqueness validation come thru.

You can use:

  validates :user_id, uniqueness: { scope: :question_id }  

and to be 100% on the safe side, add this validation on your db (MySQL ex)

  add_index(:question_votes, [:user_id, :question_id], unique: true)  

and then you can handle in your controller using:

  rescue ActiveRecord::RecordNotUnique  

So now you are 100% secure that you won't have a duplicated value :)

Answer by Francisco Balam for How do you validate uniqueness of a pair of ids in Ruby on Rails?


When you are creating a new record, that doesn't work because the id of your parent model doesn't exist still at moment of validations.

This should to work for you.

class B < ActiveRecord::Base    has_many :ab    has_many :a, :through => :ab  end    class AB < ActiveRecord::Base    belongs_to :b    belongs_to :a  end    class A < ActiveRecord::Base    has_many :ab    has_many :b, :through => :ab      after_validation :validate_uniqueness_b      private    def validate_uniqueness_b      b_ids = ab.map(&:b_id)      unless b_ids.uniq.length.eql? b_ids.length        errors.add(:db, message: "no repeat b's")      end    end  end  

In the above code I get all b_id of collection of parameters, then compare if the length between the unique values and obtained b_id are equals.
If are equals means that there are not repeat b_id.

Note: don't forget to add unique in your database's columns.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.