Получение пересечения двух активных отношений записи, рельсы

В этом приложении rails у меня есть метод, вызываемый контроллером, который принимает активное отношение записи сайтов и массив фильтров, метод возвращает любые сайты в отношении, которые имеют все фильтры в массиве. Вот метод:

def filter_sites(sites, filters)

  if filters.count > 0
    filterable = sites.tag_join
    filters.each { |f| sites = sites & filterable.with_tag(f) }
  end 

  return sites
end

Вот области, которые используются:

def self.tag_join
  joins(:tags).distinct
end

def self.with_tag(tag_id)
  where('sites_tags.tag_id = ?',tag_id)
end

Это работает правильно, но проблема в том, что он возвращает массив. Мой вопрос; есть ли более эффективный способ или написать этот метод и вернуть отношение активной записи? Как и далее в коде, дальнейшие запросы должны быть объединены в цепочку.

Любая помощь очень ценится.


person Phil Brockwell    schedule 22.07.2016    source источник
comment
Посмотрите на метод or из активной записи   -  person max pleaner    schedule 23.07.2016
comment
Один из способов сделать это — но это некрасиво — использовать SQL INTERSECT. Вы в основном создаете идентичный запрос для каждого тега, а затем INTERSECT их. Это ужасно, потому что вам нужно делать это вручную, но это работает и возвращает объект ActiveRecord, который вы можете сцепить. Я также должен спросить: не могли бы вы сделать sites.where('sites_tags.tag_id = ?', filters[0]).where('sites_tags.tag_id = ?', filters[1]).where(...)?   -  person henrebotha    schedule 23.07.2016
comment
Разве это не так же некрасиво? Это массив тегов переменной длины, поэтому его нужно записывать в цикле. Я бы подумал, что это рельсовый способ сделать это, его довольно распространенная функциональность...   -  person Phil Brockwell    schedule 24.07.2016


Ответы (1)


Вы можете выполнить слияние. Будет возвращен array, но это чистый вызов, удобный и простой в обслуживании.

person s1mpl3    schedule 31.12.2016