#ruby-on-rails #datagrid #reporting
#ruby-on-rails #datagrid #отчет
Вопрос:
На моей голове не осталось волос (а их у меня было много :)), я вырываю свои волосы и, хоть убей, не могу в этом разобраться.
У меня есть отношения «один ко многим» между двумя таблицами. Я установил драгоценный камень Datagrid для создания отчетов. Мне нужно получить отчет из одной модели на основе другой.
Пожалуйста, взгляните на мой код.
reports_grid.rb
class ReportsGrid
include Datagrid
scope do
Land.includes(:estate)
end
filter(:estate, :enum, :select => proc { Estate.group("title").select("title").map {|c| [c.title] }})
column(:id, :header => "Land ID")
column(:current_stage, :header => "Stage")
column(:price)
column(:status)
end
reports_controller.rb
class ReportsController < ApplicationController
def index
@grid = ReportsGrid.new(params[:reports_grid]) do |scope|
if params[:reports_grid].present?
if params[:reports_grid][:estate].present?
scope.joins(:estate).where("estates.title = ? ",params[:reports_grid][:estate]).page(params[:page])
**# when I get the @grid.assets here all good and return correct number of rows**
else
scope.page(params[:page])
end
else
scope.page(params[:page])
end
end
end
end
Land.rb
belongs_to :estate
estate.rb
has_many :lands
Теперь, когда я захожу в / reports и пытаюсь запустить фильтр, я получаю следующую ошибку
PG::UndefinedColumn: ERROR: column lands.estate does not exist LINE 1: ..._id" WHERE (estates.title = 'Olive Gardens' ) AND "lands"."e... ^ : SELECT COUNT(*) FROM "lands" INNER JOIN "estates" ON "estates"."id" = "lands"."estate_id" WHERE (estates.title = 'Olive Gardens' ) AND "lands"."estate" = 'Olive Gardens'
Почему Gem пытается добавить "lands"."estate" = 'Olive Gardens'
к запросу, когда я определил его в экземпляре.
Пожалуйста, дайте мне знать, если вам нужно, чтобы я что-нибудь добавил. Заранее благодарю вас.
Редактировать:
Это то, что я сделал и над чем работал в фильтре: я сделал это:
filter(:estate_id, :enum,
:select => lambda {Estate.all.map {|p| [p.title, p.id]}},
:multiple => false,
:include_blank => true
) do |value|
self.where(:lands => {:estate_id => value})
end
Считаете ли вы, что это хороший подход?
Я думаю, в рамках, которые я мог бы сказать, Land.joins(:estate)
затем используйте scope.all.map...
в запросе.
Ответ №1:
Фильтр Datagrid предназначен для фильтрации данных, но не только по умолчанию. Если у вас есть какая-то причина, по которой estate
не следует фильтровать данные самостоятельно, добавьте :dummy => true
опцию:
filter(:estate, :enum, :select => ..., :dummy => true)
Но я бы рекомендовал это. Сделайте это вместо этого, и ваши волосы начнут расти мгновенно:
filter(:estate, :enum, :select => ...) do |scope, value|
scope.joins(:estate).where("estates.title = ? ", value)
end
Это кажется очевидным из документации здесь:
https://github.com/bogdan/datagrid/wiki/Filters#filter-block
Ответ №2:
Попробуйте использовать ссылки
Land.includes(:estate).references(:estates)