Как охватить и сопоставить все категории - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть список групп, которые я хочу фильтровать по категориям.

Например: у группы № 1 есть «Категория A» и «Категория B». У группы № 2 есть «Категория B» и «Категория C»

Прямо сейчас, если я ищу «Категория A»", Появляется группа № 1.Если я ищу «Категории B» и «Категория C», появляются обе группы.

Как мне использовать область в Rails, где, если я ищу «Категории B» и «Категория C», толькоПоявляется группа №2?

Модель группы

class Group < ApplicationRecord
  has_many :group_categories
  has_many :categories, through: :group_categories

  scope :category, -> (category) { joins(:categories).where(categories {name: category}) }
end

Категория Модель

class Category < ApplicationRecord
  validates :name, presence: true
end

Модель GroupCategory

class GroupCategory < ApplicationRecord
  belongs_to :category
  belongs_to :group
end

1 Ответ

0 голосов
/ 24 декабря 2018

Вы не можете сделать прямую цепочку, потому что Group.category('A').category('B') будет возвращать только те группы с категориями, в которых имя категории является и «A», и «B», и это невозможно (имя может иметь только одно значение)

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

ids = Group.category('A').pluck(:id) & Group.category('B').pluck(:id) 
Group.where(id: ids)

Чтобы создать метод Group, который работаетс любым количеством категорий, вы можете сделать ...

def self.matching_categories(*category_array)
  ids = category_array.map{|category| Group.category(category}.pluck(:id)}.inject(:&)
  Group.where(id: ids)
end

Что позволяет вам сделать ...

Group.matching_categories('A', 'B')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...