I am trying to access specific objects through associations applied one after the other on a collection. For example, one of my database request would be :
get_current_user.readable_projects.cards.find(params[:card_id]).tasks
get_current_user returns a unique User, readable_projects a collection of projects that this user can read. So far, so good. However, each project has many cards, and I'd like to retrieve all the cards from each project I have in the collection, so that in this result I can do a find for a specific card, and then retrieve its tasks, the association between Card and Task being also a has_many.
I could iterate through the projects with a each, but the problem is I want to use the default behavior of a find, so that if in all the cards from all the projects I don't find the one I was looking for, the default RecordNotFound routine is triggered. I could also use find_by and raise the exception manually, doing something like that :
@projects = get_current_user.readable_projects
@projects.each do |p|
@found = p.cards.find_by(id: params[:card_id])
break if @found.present?
end
if @found.present?
@tasks = @found.tasks
else
raise ActiveRecord::RecordNotFound
end
However my main objective is to get this card in a way anyone reading the code could easily understand what I am doing here.
All my model relationships are what follow :
User.rb :
has_many :reader_projects, -> { where "memberships.status = #{Membership::ACTIVE} AND memberships.role_id >= #{Membership::READER} " },
through: :memberships, :class_name => 'Project', :source => :project
has_many :contributor_projects, -> { where "memberships.status = #{Membership::ACTIVE} AND memberships.role_id >= #{Membership::CONTRIBUTOR} " },
through: :memberships, :class_name => 'Project', :source => :project
has_many :admin_projects, -> { where "memberships.status = #{Membership::ACTIVE} AND memberships.role_id >= #{Membership::ADMIN} " },
through: :memberships, :class_name => 'Project', :source => :project
def readable_projects
self.reader_projects + self.contributable_projects
end
def contributable_projects
self.contributor_projects + self.administrable_projects
end
def administrable_projects
self.admin_projects
end
Project.rb :
has_many :cards, inverse_of: :project, dependent: :destroy
Card.rb :
has_many :tasks, inverse_of: :card, dependent: :destroy
My question is : is there a way to do such kind of request in one very understandable line ? Thank you in advance for your help.