Как сделать фильтр, а затем найти потомков Ancestry?

После прочитав это (ответ @thomasfedb), я это будет работать:

@categories = Category.joins(:category_users).where("category_users.user_id = ? AND category_users.interested_learning IS TRUE", current_user.id)
@search = Resource.joins(:categories).where(category_id: @categories.subtree_ids).search_filter(params[:search_filter]).paginate(:per_page => 20, :page => params[:page]).search(params[:q])

Но вместо этого я получаю эту ошибку

undefined method `subtree_ids' for #<ActiveRecord::Relation:0x007fce832b1070>

Я также попробовал ответить @Rahul из здесь

Без потомков предков это работает так

@search = Resource.joins(:category_users).where("category_users.user_id = ? AND category_users.interested_learning IS TRUE", current_user.id).search_filter(params[:search_filter]).paginate(:per_page => 20, :page => params[:page]).search(params[:q])

Хотя я хочу выполнить поиск Ransack после нахождения потомков, ошибка появляется и без Ransack. По этой причине я не включил его в заголовок. Без Рансака было бы так:

@categories = Category.joins(:category_users).where("category_users.user_id = ? AND category_users.interested_learning IS TRUE", current_user.id)
@resources = Resource.joins(:categories).where(category_id: @categories.subtree_ids)

Буду признателен за любые советы по этому поводу, которые могут сработать


person Claudio Shigueo Watanabe    schedule 12.12.2013    source источник
comment
Я только что обновил свой ответ, указав лучший способ получить соответствующие идентификаторы. Исходное решение, которое я предоставил, вызовет запрос N+1, который будет становиться все более неэффективным по мере того, как вы выбираете больше категорий. Я также прошел через способ извлечения этих идентификаторов.   -  person Damien Roche    schedule 13.12.2013


Ответы (1)


@categories.subtree_ids не будет работать, потому что subtree_ids является методом экземпляра, тогда как вы вызываете метод ActiveRecord::Relation. Попробуйте это вместо этого:

@categories.map(&:subtree_ids).flatten.uniq

Это может быть не особенно эффективно, но родословная хранит и анализирует столбец, аналогичный «10/1/3», для управления иерархией. Вышеприведенное, скорее всего, вызовет запрос N+1. Другим вариантом может быть самостоятельный анализ столбцов. Я не уверен, что родословная обеспечивает лучший способ сделать это, но это довольно просто:

arr = @categories.pluck(:ancestry)
#> ["10/1", "5/6/1", "2", nil, nil]

arr.compact
#> ["10/1", "5/6/1", "2"]

arr.map { |ids| ids.split('/') }
#> [["10","1"],["5","6","1"],["2"]]

arr.flatten
#> ["10","1","5","6","1","2"]

arr.uniq
#> ["10","1","5","6","2"]

arr.map(&:to_i)
#> [10,1,5,6,2]

Соберите все это вместе (я бы предложил многострочный метод):

@categories.pluck(:ancestry).compact.map { |ids| ids.split('/') }.flatten.uniq.map(&:to_i)
#> [10,1,5,6,2]
person Damien Roche    schedule 12.12.2013