How to write a deep join query for a filter in rails 6?

Viewed 32

I'm trying to write a filter. I have an orders model that has multiple services and each service has one worker assigned to perform it. I want to filter the order by the selected employee who performs any service in this order. I'm trying to do @orders = Order.joins(:services).joins(:employees).where(services: {employees: {id: params[:employee_id]}}), I know that this is not correct. Please tell me how to make such a request.

order.rb

class Order < ApplicationRecord
  has_many :order_services, dependent: :destroy
  has_many :services, through: :order_services
end

order_service.rb

class OrderService < ApplicationRecord
  belongs_to :order
  belongs_to :service
  belongs_to :employee

  validates :order, presence: true
  validates :service, presence: true
  validates :employee, presence: true
end

service.rb

class Service < ApplicationRecord
  has_many :order_services, dependent: :destroy
  has_many :orders, through: :order_services
  belongs_to :employee, optional: true
end

employee.rb

class Employee < ApplicationRecord
  has_many :order_services
  has_many :services, through: :order_services
end

I want to note that my order_service model is a connecting model for the service and for the employee. In theory, the connection of the order and the service can only be in the presence of a worker. + an additional question is whether such interaction is not a bad practice, or it would be better to divide them into order_service and service_employee? Thanks.

2 Answers

I think this is what you are asking for.

@orders = Order.joins(:services).where(services: { employee_id: params[:employee_id] }).distinct

It was a mistake to try to get to the employee through the service, because access to it is much closer. We do not need to call an employee through the service, because this employee is recorded in the order_service table, since by condition we have an order and service connection in the presence of an employee, therefore we can not take service into account at all.

Order.joins(:order_services).where(order_services: {employee_id: params[:employee_id]})
Related