Search code examples
rubyruby-on-rails-5rails-activerecord

Rails join query based on associated records column value


I have two models:

Project

attributes: id, status (open, cancelled, reopened)
has_many: todos 

Todo

attributes: id, project_id, status (done, partially_done, pending)
belongs_to: project

I have to tabs: Done and Pending In these two tabs I have to show projects based on associated todo status.

Project.all.includes(:todos).where(todos: {status: ['done', 'partially_done']})

It'll return Projects, where the associated todos are in done/partially_done status.

Let's say: I have two projects:

Project 1 -> Todo 1 (done), Todo 2 (partially_done), Todo 3 (pending)
Project 2 -> Todo 4 (done), Todo 5 (partially_done), Todo 6 (done)

In the done tab: it'll show only Project 2 (as all todos are done or partially done)

In the pending tab it'll show only Project 1 (as one todo is still in pending state)

How can I filter the projects based on todos?

I can do something like:

pending_projects = Project.joins(:todos).select{|project| project.todos.any?(&:pending?)}

But it seems time consuming. any way to do this effectively?

Thanks in advance!


Solution

  • You can do something like this:

    pending_projects = Project.joins(:todos).where(todos: { status: :pending })
    

    This way you cede all the job of finding proper records to DB engine, which is correct.