【问题标题】:rails 3.2 a little sorting issuerails 3.2 有点排序问题
【发布时间】:2013-09-03 22:52:10
【问题描述】:

我正在做一个可搜索和可排序的表格。实际上,除了一些小细节之外,我已经做到了。我正在根据列名进行排序,但 rails 拒绝识别其中的 1 个。现在,这就是我的 index.html.erb:

<table class="pretty" border="1" cellpadding="10">  
  <tr>
    <th><%= sortable("machine_name",       "M.Name")       %></th>
    <th><%= sortable("machine_brand",      "M.Brand")      %></th>
    <th><%= sortable("machine_model",      "M.Model")      %></th>
    <th><%= sortable("control_unit_brand", "C.Unit Brand") %></th>
    <th><%= sortable("control_unit_model", "C.Unit Model") %></th>
    <th><%= sortable("tool_axis_x",        "Axis X")       %></th>
    <th><%= sortable("tool_axis_y",        "Axis Y")       %></th>
    <th><%= sortable("tool_axis_z",        "Axis Z")       %></th>
    <th><%= sortable("rotary_axis_number", "R.Axis")       %></th>
    <th><%= sortable("linear_axis_number", "L.Axis")       %></th>
    <th><%= sortable "description"                         %></th>
    <th><%= sortable("name",               "Developer")    %></th>
    <th><%= sortable "updated_at"                          %></th>
  </tr>  

  <% for conf in @confs %>  
  <tr class="<%= cycle('oddrow', 'evenrow') -%>">
    <td><%= link_to conf.machine_name, conf %></td>
    <td><%= conf.machine_brand %></td>
    <td><%= conf.machine_model %></td>
    <td><%= conf.control_unit_brand %></td>
    <td><%= conf.control_unit_model %></td>
    <td><%= conf.tool_axis_x %></td>
    <td><%= conf.tool_axis_y %></td>
    <td><%= conf.tool_axis_z %></td>
    <td><%= conf.rotary_axis_number %></td>
    <td><%= conf.linear_axis_number %></td>
    <td><%= conf.description %></td>
    <td><%= conf.developer.name unless conf.developer_id.blank? %></td>
    <td><%= conf.updated_at %></td>
  </tr>
  <% end %>
</table>

您可以通过 developer_id 查看我如何联系模型 Conf 的开发人员并显示其名称。这部分正在工作,但是在排序时它会中断!可排序操作使用 sort_column,就是这样:

def sort_column
    ( (User.column_names.include?(params[:sort])) || (Conf.column_names.include?(params[:sort])) ) ? params[:sort] : "machine_name"
end

用户是一个模型。 Conf 是另一种模式。用户 has_many confs。会议

belongs_to :developer, :class_name => 'User', :foreign_key => 'developer_id'

我认为 rails 尝试按名称排序,但 conf 没有名称,出现类似错误

no such column: name: SELECT  "confs".* FROM "confs"

Sort_column 使用用户的列定义,但我认为 rails 的行为是因为用户的列与开发人员的列不同。如何制作导轨以识别开发人员列? 注意:我尝试了 Conf.developer.column_names.include?... 但收到错误“未定义的方法开发人员”

【问题讨论】:

    标签: ruby-on-rails ruby sorting


    【解决方案1】:

    最简单的解决方案是在拉取数据时添加一个'developer_name'列:

    @conf = your_current_logic.
              includes(:developer).                               # eager load your developer relation
              where('users.id IS NULL OR users.id IS NOT NULL').  # a meaningless filter to force a LEFT JOIN
              select("confs.*, users.name as developer_name")
    

    然后您可以在可排序列中引用“developer_name”。

    或者,您可以简单地将sortable('name', ...) 替换为sortable('users.name', ...)。您可能需要修改您的 sort_column 逻辑以允许此约定。

    一种方法可能是这样的:

    def sort_column
      if params[:sort] =~ /([^\.]+)\.([^\.]+)/ &&             # check if 'table.column' format is used
           %w(users confs).include? $1 &&                     # check if table name matches expectations
           $1.classify.constantize.column_names.include?($2)  # check if column is present in table's class
        params[:sort]    # 'table.column' format
      elsif Conf.column_names.include?(params[:sort]))        # if 'column' format is used, just check Conf class
        params[:sort]    # 'column' format
      else
        "machine_name"   # default sort column
      end
    end
    

    更新

    因此使用第二种方法,您的数据检索可能如下所示:

    @confs = Conf.search(params[:search]).
                  includes(:developer).
                  where('users.id IS NULL OR users.id IS NOT NULL').
                  order(sort_column + ' ' + sort_direction).
                  paginate(:per_page => 10, :page => params[:page])
    

    并且任何不明确的列(例如updated_at)都应该用表名来限定:

    <th><%= sortable "confs.updated_at"                      %></th>
    

    由于您将需要限定名称,因此听起来第二种方法是可行的方法。请注意,使用classify.constantize 动态检查模型类可能存在风险 - 您可以使用可用类的白名单来缓解这种情况。更新以证明这一点。

    【讨论】:

    • 感谢您的回复,您的第一个建议给出了错误“没有这样的列 users.name 作为 developer_name ...”。制作sortable('users.name', ...) 不会出错,但不会排序,什么都不做
    • @kalahari:对于第一个建议,假设您加入开发者协会是您逻辑的一部分。我发现您可能并非如此 - 已更新以适应此情况。对于第二个建议,我提到您需要修改 sort_column 方法逻辑。更具体地说,如果您得到“。”,则检查“用户”列中的“名称”。排序参数的分隔字符串。
    • def index @confs = Conf.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page =&gt; 10, :page =&gt; params[:page]) end 这是我的第一个索引。在更改了您的第一个建议后,它说 ambiguous column name: updated_at 并且不要生我的气,我是 Rails 的初学者学习者,您的新第二种方式对我来说似乎是外来工作:) 现在尝试第二种方式并获得 no such column: users.name
    • @kalahari,第二种方法(或任何尝试在数据库中排序的方法)也必须在 users 表上包含一个连接,以便可以对其进行排序。您可以使用与第一种方法相同的includeswhere。回复:不明确的列名错误,如果您引用存在于多个表中的列名,除非您使用要使用的表名对其进行限定 - 更新以解释如何执行此操作,否则您会收到此错误。跨度>
    猜你喜欢
    • 2013-08-12
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多