2014-01-09 2 views
3

Предположим, у меня есть таблица posts, а другая таблица reviews, которая имеет post_id и rating (целое число).Как фильтровать списки индексов ActiveAdmin по таблице соединений?

Как добавить фильтр в app/admin/post.rb, который возвращает сообщения с определенным итоговым счетом? (например, SUM (review.rating) GROUP BY (posts.id)). Я хочу, чтобы фильтр отображался с правой стороны индекса вместе с другими фильтрами и в идеале работал как вход диапазона.

Чтобы быть ясным, когда я говорю «фильтр», я имею в виду метод ActiveAdmin filter, который добавляет фильтры в правую боковую панель на индексной странице.

Я создал область в Post, которая возвращает сообщения с оценками, но я не смог найти способ использовать это в ActiveAdmin-фильтре.

Примечание: Я переписал свой пример, потому что мой первоначальный не учитывал сложность вопроса.

+0

Я в замешательстве; вы хотите выполнять эти запросы как фильтр, область или оба? – seanlinsley

+0

Конечная цель состоит в том, чтобы иметь возможность фильтровать по вычисленному значению на странице индекса сообщений. Я написал область, потому что я хотел убедиться, что запрос был прав, и я подумал, что это будет гибкий и простой способ добавить его в ActiveAdmin. Однако пока я не нашел способа сделать это. –

+0

https://github.com/activerecord-hackery/ransack/issues/70 – Fivell

ответ

1

Использование колонки кэш счетчика для хранения отсчитывать комментарии

http://railscasts.com/episodes/23-counter-cache-column

Затем колонна будет обновляться каждый раз, когда комментарий создается для того Post.this бы также помочь в повышении эффективности поиска.

+0

Спасибо. Ситуация на самом деле сложнее, чем пример, который я дал, поэтому счетчик кеша не работает. Я пытался сделать это простым, но, видимо, я сделал пример слишком простым :) Я обновил свой вопрос, чтобы объяснить это. Вы знаете, как напрямую обращаться к моделям соединения/областям? –

2

Это common to override scoped_collection to join associated records для повышения производительности:

ActiveAdmin.register Post do 
    controller do 
    def scoped_collection 
     super.includes :author, :publisher 
    end 
    end 
end 

Поскольку вся коллекция теперь автор и издатель включен, вы можете иметь объем, который запрашивает те:

scope :random_house do |scope| 
    scope.where publishers: {name: 'Random House'} 
end 
+0

Это, безусловно, выглядит полезно, но я до сих пор не знаю, как добавить фильтр, используя эту область. Я надеялся на что-то вроде 'filter scope:: random_house, as:: checkbox'. –

+0

Хотя в моем случае это даже сложнее, потому что мое значение вычисляется, поэтому мне нужен Ransack для генерации 'HAVING SUM (review.rating)> 100' или что-то в этом роде (вместо использования WHERE). Вот почему я надеялся использовать область, которую я уже написал, вместо того, чтобы понять, как заставить Ransack генерировать сложный SQL. –

+0

«Размер фильтра:: random_house, as:: checkbox» будет лучше написан как поле выбора для выбора из разных издателей. Например: 'filter: publisher_name, as:: select, collection: -> {Publisher.uniq.pluck: name}' – seanlinsley

3

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

Я могу изменить scoped_collection на основе параметра запроса и просто передать параметр, когда захочу его использовать. Например, если у меня есть объем with_rating (х), которая возвращает сообщения со счетом по крайней мере х, я могу написать:

controller do 
    def scoped_collection 
    if params[:with_rating] 
     super.with_rating(params[:with_rating]) 
    else 
     super 
    end 
    end 
end 

Тогда я могу пойти /admin/posts?with_rating=100 и получить обратно сообщения с рейтингом в не более 100.

Спасибо @seanlinsley за то, что он сообщил мне о методе scoped_collection, который я использовал в этом решении.

Смежные вопросы