Метод области действия Rails для «включенного во многие ко многим» - PullRequest
0 голосов
/ 06 февраля 2019

Метод области действия ниже находится в моем классе Deal.Сделка has_many origins (которые Airports. Таким образом, Deal.from_airport(dca) вернет все сделки из DCA.

scope :from_airport, -> (airport) {select {|d| d.origins.include? airport }}

Этот метод работает нормально, но возвращает массив. Есть ли способреализовать это так, чтобы оно возвращало отношение ActiveRecord?


Повторное обновление: Благодаря @NeverBe, теперь у меня установлены первые два «множественных» фильтра (я использовал его / ее ответ для первогочтобы понять, как построить второе):

  scope :from_airports, -> (airports) { 
    joins(:origins).where(airports: {id: airports.map(&:id)}) 
  } 

  scope :to_regions, -> (regions) { 
    joins(:region).where(regions: {id: regions.map(&:id)}) 
  } 

Однако у меня все еще проблемы с for_vacations.

, так как

  1. он имеет дело не с отношениями (например, Deal has_many :airports; belongs_to :region), а со свойствами (start_date и end_date) и

  2. , он имеет дело с сравнением, а не с равенством,

Приведенные выше методы с использованием SQL, такие как WHERE "airports"."id" IN (2502, 2686, 2816), не работают.

Ниже приведен "старый" код, а также мой лучший пример метода, который возвращает Relation.

  # "Old" code: Returns the right objects, but as an array rather than as an ActiveRecord relation
  scope :for_vacations, -> (vacations) do
    select do |deal|
      vacations.any? do |v| 
        v.deals.include? deal 
      end
    end
  end

  # "New" code: Throws error, see below.
  scope :for_vacations, -> (vacations) { 
    where.not('start_date >= ?', vacations.map(&:end_date))
    .where.not('end_date <= ?', vacations.map(&:start_date))
  }

Новый код выдает эту ошибку:

     ActiveRecord::StatementInvalid:
       PG::DatatypeMismatch: ERROR:  argument of NOT must be type boolean, not type record
       LINE 1: SELECT "deals".* FROM "deals" WHERE NOT (start_date >= '2020...
                                                       ^
       : SELECT "deals".* FROM "deals" WHERE NOT (start_date >= '2020-12-31','2020-10-31','2020-03-31') AND NOT (end_date <= '2019-12-01','2019-10-01','2019-03-01')
     # ./spec/models/deal_scopes__filters_spec.rb:110:in `block (3 levels) in <main>'
     # ------------------
     # --- Caused by: ---
     # PG::DatatypeMismatch:
     #   ERROR:  argument of NOT must be type boolean, not type record
     #   LINE 1: SELECT "deals".* FROM "deals" WHERE NOT (start_date >= '2020...

Есть ли герои на помощь?

1 Ответ

0 голосов
/ 06 февраля 2019

Попробуйте это

scope :from_airport, -> (airport) {joins(:origins).where(airports: {id: airport.id}) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...