Tarscher
Tarscher

Reputation: 1933

validates_uniqueness_of scope on other table

A User belongs to Groups, a Group belongs to a Company

I want to verify that the username of the user is unique per company. So my database can have multiple dublicate usernames as long as they belong to a different company.

A logical step would be to use validates_uniqueness _of scope and use the company id (stored in groups). Is there a way scope can get access to other tables or do I need to solve this ina different way?

thanks

Upvotes: 1

Views: 1557

Answers (3)

SuddenlyAwakened
SuddenlyAwakened

Reputation: 107

I had this issue as well and came to research an answer. I used Tarscher answer to come up with the following solution.

    validates_each :username do |record, attr, value|
      if User.joins(:group).where('username = ? and groups.company_id = ?', record.username, record.group.company_id).present?
        record.errors.add attr, 'This username is already taken by some on in your company'
      end
    end

Upvotes: 1

Tarscher
Tarscher

Reputation: 1933

Making a custom validation rules is probably the best way to tackle this problem.

Upvotes: 1

Rishav Rastogi
Rishav Rastogi

Reputation: 15492

In this design, I see a problem, if a User can belong to one group, and that a group can belong to one company. But the association of User and Company is very indirect, where as in reality it should be direct, independent of its association with the group.

So for example to change companies a User switches groups, not companies, which is not entirely right. It may make sense in your context I am not sure.

So storing company information in the User table would make sense ( as for uniqueness test as well, the relationship is direct).

and

 validation_uniqueness_of :user, :scope=> company_id 

would work.

Update

I am not asking you to denormalize tables, the group still may be tightly tied to the company. But that relationship has nothing to do with the user-company

My point is basically, User object should have direct visibility into the Company class, not through "Group".

That means adding a company column into your table, thats all, and establishing a direct relationship b/w user and Company.

and it wouldn't be so much of a management hassle.Plus, I sort of expect, to write something like

"user.company"

Instead of

"user.group.company".

In any case. Thats just my view, I don't know the whole context, so my advice is based on what I saw in your question

Upvotes: 3

Related Questions