带Turbo框架的Rail中按嵌套模型属性对表格进行排序

68bkxrlz  于 2022-10-15  发布在  Ruby
关注(0)|答案(1)|浏览(119)

我正在创建一个Employees表,并且我想按FULL_RATE_PENCE排序,这是HourlyRate的一个属性。每个员工都有许多小时工资率,这构成了加薪或减薪的历史。问题是试图访问嵌套的HourlyRate,因为我需要访问的HourlyRate在集合中。由于使用了:Includes,因此无法使用.find或.find_by
最初,我收到以下错误:
使用非属性参数调用了危险的查询方法(其参数用作原始SQL的方法):“hourly_rates.first st.ull_rate_pence asc”。不应使用用户提供的值(如请求参数或模型属性)调用此方法。已知的安全值可以通过将它们 Package 在Arel.sql()中来传递。
然后,在使用Arel.sql() Package 部件之后,我收到了下一个错误:
SQlite3::SQLException:没有这样的列:Hourly_rates.Full
模型

class Employee < ApplicationRecord
    has_many :hourly_rates
    accepts_nested_attributes_for :hourly_rates
end
class HourlyRate < ApplicationRecord
    belongs_to :employee
    monetize :full_rate_pence, as: 'full'
end

表中的链接

<th scope="col">
  <%= sort_link(column: "hourly_rates.first.full", label: "Hourly Rate") %>
</th>

用于创建链接的帮助器方法

def sort_link(column:, label:)
      if column == params[:column]
        link_to(label, list_employees_path(column: column, direction: next_direction))
      else
        link_to(label, list_employees_path(column: column, direction: 'asc'))
      end
    end

控制器法

def list
  employees = Employee
      .includes(:hourly_rates)
      .where(hourly_rates: {active:true})
      .order(Arel.sql("#{params[:column]}"))
    render(partial: 'employees', locals: { employees: employees })
end

感谢您的建议,我如何才能实现这一点。

rkkpypqq

rkkpypqq1#

Ruby回答:
类似于:

def list
  employees = Employee
      .includes(:hourly_rates)
      .where(hourly_rates: {active:true})

  # you can add to the query before the end:
  case params[:column]
  when "Hourly Rate"
    employees = employees.order(hourly_rates.first.full)
  else
    employees = employees.order(id)
  end

  render(partial: 'employees', locals: { employees: employees })
end

JavaScript排序:

var asc = 0;
function sort_table(table, col) {
    $('.sortorder').remove();
    if (asc == 2) { asc = -1; } else { asc = 2; }
    var rows = table.tBodies[0].rows;
    var rlen = rows.length;
    if (!table.tHead) { rlen--; }
    var arr = new Array();
    var i, j, cells, clen;
    // fill the array with values from the table
    // does not like empty rows, so check your haml!
    for (i = 0; i < rlen; i++) {
        cells = rows[i].cells;
        clen = cells.length;
        arr[i] = new Array();
        for (j = 0; j < clen; j++) { arr[i][j] = cells[j].innerHTML; }
    }
    // sort the array by the specified column number (col) and order (asc)
    arr.sort(function (a, b) {
        var retval = 0;
        var col1 = a[col].toLowerCase().replace(',', '').replace('$', '').replace(' usd', '')
        var col2 = b[col].toLowerCase().replace(',', '').replace('$', '').replace(' usd', '')
        var fA = parseFloat(col1);
        var fB = parseFloat(col2);
        if (col1 != col2) {
            if ((fA == col1) && (fB == col2)) { retval = (fA > fB) ? asc : -1 * asc; } //numerical
            else { retval = (col1 > col2) ? asc : -1 * asc; }
        }
        return retval;
    });
    for (var rowidx = 0; rowidx < rlen; rowidx++) {
        for (var colidx = 0; colidx < arr[rowidx].length; colidx++) { table.tBodies[0].rows[rowidx].cells[colidx].innerHTML = arr[rowidx][colidx]; }
    }

    hdr = table.rows[0].cells[col];
    if (hdr.children.length == 0) {
        obj = hdr
    } else {
        obj = hdr.children[0]
    }
    if (asc == -1) {
        // $(hdr).html($(hdr).html() + '<span class="sortorder">▲</span>');
        $(obj).html($(obj).html() + '<span class="sortorder">▲</span>');
    } else {
        //$(hdr).html($(hdr).html() + '<span class="sortorder">▼</span>');
        $(obj).html($(obj).html() + '<span class="sortorder">▼</span>');
    }
}

从视野中呼唤:

:javascript
  function sortTable(n) {
  sort_table(document.getElementById("indextable"), n);
  }
%table#indextable
  %thead
    %tr
      %th{ onclick: 'sortTable(0)' } Name
      %th{ onclick: 'sortTable(1)' } Machine
      %th{ onclick: 'sortTable(2)' } Method
      %th{ onclick: 'sortTable(3)' } Bands
  %tbody
    // etc.

相关问题