'One to Many Active Records Ruby on Rails

I am working on data capturing system built on ruby on rails. I am stuck at a point and already spent hours on this. I have one to many relationship where I need to get data based on status filters. I have two tables:

  1. Stacks 2) Adjudication One stack can have multiple adjudications. Now the scenario is that I have to filter data from db based on status. If I select "is_pending" status I need to get all the data that do not have a row in the adjudication table plus If It has a row in the adjudication table only get those rows which "is_ready" and "is_final" column is false.

My Controller:

def index
      @pagy, @stacks  = pagy(@study.stacks.filter_by_status(filtering_params(params)))
end

# A list of the param names that can be used for filtering the stack list
def filtering_params(params)
     params[:status]
end

My Model:

 #scope
  scope :filter_by_status, -> (status) {
      if status.present?
        if status == "is_final"
          joins(:adjudication).where("adjudications.is_final": true)
        elsif status == "is_ready_to_adjudicate"
          joins(:adjudication).where("adjudications.ready_for_adjudication": true, "adjudications.is_final": false)
        elsif status == "is_pending_grading"
         **????????????????? Stuck Here ?????????????????**
        end
      end
  }

I will appreciate if anyone can guide me through this.



Solution 1:[1]

after hours of searching, I found out that Left join can be helpful in this case, plus we need to use "is NULL" check on ID as it will give us the null records while where condition will return matching rows.

 #scope
  scope :filter_by_status, -> (status) {
      if status.present?
        if status == "is_final"
          joins(:adjudication).where("adjudications.is_final": true)
        elsif status == "is_ready_to_adjudicate"
          joins(:adjudication).where("adjudications.ready_for_adjudication": true, "adjudications.is_final": false)
        elsif status == "is_pending_grading"
          includes(:adjudication).where("adjudications.ready_for_adjudication": false, "adjudications.is_final": false)
          .or(includes(:adjudication).where("adjudications.stack_id": nil))
        end
      end
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Amir Khan