Hi guys, how to validate a Rails belongs_to association in most effective way? Did you ever think about that? I am asking this question because there is something that most of the people will not notice. I can explain.
Suppose we have 2 Models ‘User’ and ‘Group’
Condition:
Every ‘User’ must belongs to one of the ‘Group’.
So how we validate this? A simple way of doing this is:
Validate foreign key
class User belongs_to group validates :group_id, presence: true end
What this code actually does? Lets find out.
> Group.last.id # => 80 > User.new(group_id: 100).valid? # => true > Group.exists?(100) # => nil
Oops… Is that true? Not at all. So rails make us fool? Ha. The presence validator will only check a foreign key is provided to it. That’s it. And it will not check the existence of that record. So what we can do in this case? Lets check the other way of doing this.
Validate associated record
class User belongs_to group validates :group, presence: true end
Here what the validator does is it checks the record exists or not. If record not exists it returns false for valid? method.
> Group.last.id # => 80 > user = User.new(group_id: 100) > user.valid? # => false > Group.exists?(100) # => nil > user.errors.full_messages # => ["Group can't be blank"]
Wahh..great! But wait, think.. What it actually does in the background? Whenever a user record goes through the .valid? call, rails fire a database query to find this record exists or not. Is that really good? In one way. In other way it’s bad. It affects performance.
But we have to consider database integrity. So the second approach wins even though it is firing an extra query in the background. Cheers!