activerecord объединяет несколько раз в одной таблице - PullRequest
0 голосов
/ 25 октября 2019

Я делаю простой поиск, похожий на этот (с 8 различными параметрами, но я скопирую 2 только для примера)

 if params[:old] == "on"
   @events = @events.joins(:services).where(services: { name: "old" })
 end

 if params[:big] == "on"
   @events = @events.joins(:services).where(services: { name: "big" })
 end

Запрос работает нормально, когда у меня только один параметр "включен"и возвращает мои события, имеющие службу в параметре.

НО, если у меня есть два параметра "включено", даже если мое событие имеет обе службы, оно больше не работает.

Я проверялэто в консоли, и я вижу, что если я делаю .joins (: services) .where (services: {name: "big"}) на элементе, который уже был присоединен ранее, он ничего не возвращает.

Я не понимаю, почему.

Первый @events (когда один параметр) возвращает отношение активной записи с несколькими событиями внутри.

Почему я не могу сделать еще одно .соединение?

Я действительно не понимаю, что не так в этом запросе и почему он становится пустым, как только он соединяется дважды.

Большое спасибо

1 Ответ

1 голос
/ 26 октября 2019

Код, который вы используете, будет переведен в:

SELECT  "events".* FROM "events" INNER JOIN "services" ON "services"."event_id" = "events"."id" WHERE "services"."name" = ? AND "services"."name" = ? LIMIT ?  [["name", "big"], ["name", "old"], ["LIMIT", 11]]

Вот почему он возвращает нулевую запись.

Вот решение, которое я могу придумать в данный момент, не уверенесли это идеал, но да, он работает и был протестирован.

# event.rb
class Event < ApplicationRecord
  has_many :services
  has_many :old_services, -> { where(name: 'old') }, class_name: 'Service'
  has_many :big_services, -> { where(name: 'big') }, class_name: 'Service'
end


# service.rb
class Service < ApplicationRecord
  belongs_to :event
end

И ваш метод поиска можно записать так:

if params[:old] == "on"
  @events = @events.joins(:old_services)
end

if params[:big] == "on"
  @events = @events.joins(:big_services)
end

@events = @events.distinct
# SELECT  DISTINCT "events".* FROM "events" INNER JOIN "services" ON "services"."event_id" = "events"."id" AND "services"."name" = ? INNER JOIN "services" "old_services_events" ON "old_services_events"."event_id" = "events"."id" AND "old_services_events"."name" = ? LIMIT ?  [["name", "big"], ["name", "old"], ["LIMIT", 11]]
...