Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord validate :uniqueness on association

I need to perform the validation to make sure that only one user within a company can exist within a given category.

  validates  :user_id, :uniqueness => {:scope => [:category, :company_id], :message => "already exists"}

This works except the error message is set on :user_id key.

How can I do the same but set the error on the :user key (validates :user gives an error)?

like image 403
Dmytrii Nagirniak Avatar asked Jan 05 '12 07:01

Dmytrii Nagirniak


People also ask

What is Activerecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

What is scope in validation in Rails?

The scope option to the Rails uniqueness validation rule allows us to specify additional columns to consider when checking for uniqueness. class Project < ApplicationRecord belongs_to :account has_many :tasks validates :name, presence: true, uniqueness: { scope: :account_id } end.


1 Answers

Here's a simple way to check uniqueness and force the error to be assigned to the :user attribute:

class User < ActiveRecord::Base
  validate :user_unique_per_company_per_category

  private

  def user_unique_per_company_per_category
    if self.class.exists?(:user_id => user_id, :company_id => company_id, :category => category)
      errors.add :user, 'already exists'
    end
  end
end

It would be preferable, I think, if you could figure out a way to use the default validation on :user_id, but maybe you have a special use case.

Also, if you're not using this in a form, you might consider assigning the error to :base, since you might confuse future developers who expect the error to appear on :user_id:

errors.add :base, 'already exists'
like image 90
Seamus Abshere Avatar answered Oct 29 '22 01:10

Seamus Abshere