0

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.

V. Déhaye
  • 493
  • 6
  • 20

0 Answers0