Reputation: 3224
First, my associations:
Form has_many :agreements
Agreement belongs_to :student
I'm trying to define an Ability where the current user can :read, Form
when one of its agreements belongs to the the current user.
I've attempted to define the ability like so:
Ability.rb:
can :read, Form do |f|
f.agreements.select { |a| a.student_id == user.id }.nil? == false
end
I've also tried:
can :read, Form, agreements: { student_id: user.id }
Unfortunately, the first solution allows all students to view all Forms, even if they are not attached to one of the form agreements. The second solution doesn't allow any student to view a Form, even if they are attached to one of the form's agreements.
What am I doing wrong?
Upvotes: 0
Views: 347
Reputation: 6714
This line is no good:
f.agreements.select { |a| a.student_id == user.id }.nil? == false
The reason is that #select
will always return an array. If there are no agreements where the student_id
matches the user.id
, then you'll get an empty array ([]
). But #nil?
on any array, including an empty array, is always false. So this line always evaluates to true.
The fix is quite simple. Use the rails method #blank?
instead of #nil?
. That will return true if the object is nil
OR if it's empty
. And [].empty?
returns true
.
tldr: Change the above line to
f.agreements.select { |a| a.student_id == user.id }.blank? == false
Upvotes: 1