Драгоценный камень Datagrid в Rails 4 возвращает PG: неопределенный столбец: ОШИБКА:

#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)