【问题标题】:AJAX Datatables filtering with empty associations in Rails在 Rails 中使用空关联过滤 AJAX 数据表
【发布时间】:2017-08-04 19:18:53
【问题描述】:

我正在使用ajax-datatables-rails gem 来生成服务器端处理的数据表。我的数据表类看起来像这样:

class StoreDatatable < AjaxDatatablesRails::Base

  def view_columns
    @view_columns ||= {
      id: {source: "Store.id"},
      name: {source: "Store.name"},
      item_qty: {source: "Item.qty"},
      item_name: {source: "Item.name"},
    }
  end

  def data
    records.map do |record| {
      id: record.id,
      name: record.name,
      item_qty: record.item.try(:qty),
      item_name: record.item.try(:name),
    }
    end
  end

  private

  def get_raw_records
    Store.includes(:item).all
  end

end

我的数据库模型如下所示:

class Store < ApplicationRecord
  has_one :item
end

class Item < ApplicationRecord
  belongs_to: store
end

我的控制器如下所示:

def index
  respond_to do |format|
    format.html
    format.json { render json: StoreDatatable.new(view_context) }
  end
end

我的数据表的咖啡脚本如下所示:

$('#store').dataTable
  processing: true
  serverSide: true
  searching: true
  lengthMenu: [10, 25, 50, 100]
  ajax: $('#store').data('source')
  columns: [
    {data: 'id'}
    {data: 'name'}
    {data: 'item_qty',
    defaultContent: ""},
    {data: 'item_name',
    defaultContent: ""},
  ]
  deferRender: true

我可以很好地显示表格,但是当我尝试过滤表格的结果时,由于空关联而出现错误。并非所有Stores 都必须有Items,但我需要能够显示所有Stores,无论它们是否有Items(这就是为什么我使用includes 而不是joins 在我的get_raw_records 方法)。

当我尝试过滤结果时,我在 Rails 中遇到的错误是:

ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'item.qty' in 'where clause'

如何让数据表的过滤器处理空关联?关联需要是可搜索的。

我正在使用 Rails 5.1.2、Ruby 2.4.1 和最新的 Datatables 版本(包括 gem)。

【问题讨论】:

  • 我从来没有使用过这个 gem,但是如果你将 references(:item) 添加到你的 get_raw_records 会发生什么? “对于 SQL 片段,您需要使用引用来强制连接表”(from the guide)
  • 谢谢!这似乎成功了。

标签: jquery ruby-on-rails ruby ajax datatable


【解决方案1】:

根据the rails guide 谈到使用where 条件与includes 时:

像这样使用where 只会在你传递一个哈希值时起作用。对于 SQL 片段,您需要使用 references 强制连接表

因此,您可能需要添加 references(:item) toget_raw_records` 才能完成这项工作。

【讨论】:

    【解决方案2】:

    我有一个范围过滤器可以像这样工作:

    在数据表视图中,我在数据表上方创建了一个表格来输入范围变量,然后添加一些 javascript 以在更改时重新加载数据表:

              <table>
                <tbody><tr>
                    <td>Minimum CWD:</td>
                    <td><input type="text" id="minCWD" name="minCWD"></td>
                </tr>
                <tr>
                    <td>Maximum CWD:</td>
                    <td><input type="text" id="maxCWD" name="maxCWD"></td>
                </tr>
            </tbody></table>
    
    <script>
    $(document).ready(function () {             
                // other options
                var table = $('#example').DataTable()
                        
                $("#minCWD").change(function () {
                  table.ajax.reload();
                });
                $("#maxCWD").change(function() {
                  table.ajax.reload();
                });
            });
    </script>
    

    然后将过滤器变量添加到ajax调用(在咖啡文件中):

    ajax: {
          url: $('#example').data('source'),
          beforeSend: (xhr) => xhr.setRequestHeader('Content-Type', 'application/json'),
          data: (d) ->
            $.extend {}, d, 'minCWD': $('#minCWD').val(),
            $.extend {}, d, 'maxCWD': $('#maxCWD').val()
        }
    // note: the beforeSend may not be required
    

    然后在model_datatable.rb中添加一个过滤器:

    def get_raw_records
        #YOUR TYPICAL SELECTION...note: I'm using AREL and joining schools with pstats
        #now filter by your max min variables
        if params['minCWD'].present?
          schools = schools.where(pstats[:cwd_percent].gteq(params['minCWD']))
        end
        if params['maxCWD'].present?
          schools = schools.where(pstats[:cwd_percent].lteq(params['maxCWD']))
        end
        return schools
      end
    

    我的控制器如下所示:

    respond_to do |format|
          format.html
          format.json { render json: ExampleDatatable.new(params, view_context: view_context) }
    end
    

    这里的工作示例:https://schoolsparrow.com/arizona/schools

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 2015-01-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多