0

我是 Rails 的新手。我正在尝试在遗留数据库上实现类似 Ryan Bates 的可排序表列代码(Railscast #228)。我的问题与“按关联模型中的列对 Rails 数据库表进行排序”非常相似,但我似乎无法根据那里的答案解决我的问题。

我希望能够按表(Ent 类)中的索引视图对我的项目列表进行排序udtidentityudfstorage即按project.ent.udtid. 我还有一个额外的考虑,因为每个项目都匹配许多 ent 行,所以我需要将范围匹配到 where ent.rowindex != 0

模型:

class Project < ActiveRecord::Base
has_many :ent, :foreign_key => "attachtoid"
has_many :samples, :foreign_key => "projectid"

class Ent < ActiveRecord::Base
set_table_name("entityudfstorage")
belongs_to :project, :foreign_key => "attachtoid"
scope :rowindex, where('entityudfstorage.rowindex != ? ', "0")

项目索引视图:

    <tr>
    <th><%= sortable "name", "Name" %></th>
    <th><%= sortable "projecttype", "Project Type" %> </th>
    </tr>
    <tr>
    <td><%= project.name %></td>
    <td><%= project.ent.rowindex.first.udtid %></td>
    </tr>

项目负责人

def list
@projects = Project.order(sort_column + " " + sort_direction)
end

我一直在试图弄清楚我可以在 projecttype 的“sort_column”中放入什么,这将使它按关联的字段 project.ent.rowindex.first.udtid 进行排序(与“name”在控制器中的工作方式相同)按 project.name 排序)。

我尝试在以下项目中设置范围

 scope :by_udtids, Project.joins("left join ent on projects.projectid = ent.attachtoid").where('ent.rowindex != ?', 0).order("ent.udtid DESC")

然后在项目控制器中尝试了这个。

if sort_column == "projecttype"
@projects = Project.by_udtids
else
@projects = Project.order(sort_column + " " + sort_direction)

结果是项目索引页面在列中显示了正确的数据,但是当我单击“项目类型”链接标题时,它没有排序(然而,如果我单击“名称”链接标题,它确实排序。我在服务器终端中看到的日志对于两次点击都是相同的,并且查询似乎是正确的..

Started GET "/projects?direction=asc&sort=projecttype" for 128.208.10.200 at 2013-08-29 07:47:52 -0700
Processing by ProjectsController#index as HTML
Parameters: {"direction"=>"asc", "sort"=>"projecttype"}
Project Load (1.5ms)  SELECT "project".* FROM "project" ORDER BY name asc
Ent Load (0.4ms)  SELECT "entityudfstorage".* FROM "entityudfstorage" WHERE "entityudfstorage"."attachtoid" = 602 AND (entityudfstorage.rowindex != '0' ) LIMIT 1
CACHE (0.0ms)  SELECT "entityudfstorage".* FROM "entityudfstorage" WHERE "entityudfstorage"."attachtoid" = 602 AND (entityudfstorage.rowindex != '0' ) LIMIT 1
(0.3ms)  SELECT COUNT(*) FROM "sample" WHERE "sample"."projectid" = 602 
Ent Load (0.3ms)  SELECT "entityudfstorage".* FROM "entityudfstorage" WHERE "entityudfstorage"."attachtoid" = 603 AND (entityudfstorage.rowindex != '0' ) LIMIT 1
CACHE (0.0ms)  SELECT "entityudfstorage".* FROM "entityudfstorage" WHERE "entityudfstorage"."attachtoid" = 603 AND (entityudfstorage.rowindex != '0' ) LIMIT 1
(0.2ms)  SELECT COUNT(*) FROM "sample" WHERE "sample"."projectid" = 603

Rendered projects/list.html.erb within layouts/admin (478.7ms)
Completed 200 OK in 487ms (Views: 398.7ms | ActiveRecord: 87.9ms)
[2013-08-29 07:55:27] WARN  Could not determine content-length of response body. Set content-   length of the response or set Response#chunked = true

Started GET "/assets/jquery.js?body=1" for 128.208.10.200 at 2013-08-29 07:55:28 -0700
Served asset /jquery.js - 304 Not Modified (0ms)
[2013-08-29 07:55:28] WARN  Could not determine content-length of response body. Set content-   length of the response or set Response#chunked = true

非常感谢任何见解!

4

1 回答 1

0

在这种情况下,您实际上并没有说“不起作用”是什么意思。我猜这要么意味着您收到一条错误消息,要么意味着项目没有按照您期望的方式排序。

如果它是一条错误消息,您应该将它包含在您的问题中,但我会代替您做的第一件事可能是开始使用 Rails 约定来命名和引用事物。如果您的关联类是UserDefinedField,Rails 将期望表被命名user_defined_fields并且关联被指定为has_many :user_defined_fields。它还期望字段为蛇形 ( attach_to_id, 不是attachtoid),但除了必须在任何地方指定每个外键之外,这可能不会导致错误。查看您的代码,我希望 Rails 每次加载 Project 模型时都会抱怨关联名称。您应该更改这些内容以符合约定,或者(如果您有充分的理由使用这些名称)通过在关联中指定类名和表名来告诉 Rails 发生了什么。

如果这是一个不正确的响应顺序,我不太确定问题是什么。立即跳出来的一件事是,您将在此范围内多次返回同一个项目,每个关联的 UserDefinedField 一次。如果您不希望这种情况发生,您需要在group您的范围中添加一个子句,并为userdefinedfields.udtids. 这可能看起来像:

scope :by_udtids, Project.
  joins("left join userdefinedfields on projects.projectid = userdefinedfields.attachtoid").
  where('userdefinedfields.rowindex != ?', 0).
  group('projects.id').
  order("max(userdefinedfields.udtid) DESC")

编辑:看起来您当前的问题是范围根本没有被使用。以下是可能出现这种情况的几个原因:

  1. 我注意到您的控制器操作被调用ProjectsController#list,但是您的日志显示带有参数的请求正在被处理ProjectsController#index。对操作的调用list似乎没有运行任何查询,这听起来好像它没有做任何触发实际加载对象的事情。这可能只是路由或模板错误吗?

  2. 鉴于您说正在运行的查询在两种情况下都是相同的,如果正在调用正确的操作那么您的条件 () 似乎很可能sort_column == "projecttype"返回 false,即使您传递了参数也是如此。即使范围不是很正确,否则您仍然会在那里看到至少一个不同的查询。您是否可能只是忘记设置sort_column = params[:sort]?尝试暂时删除条件 - 始终使用@projects = Project.by_udtid. 看看你是否得到不同的查询。

关于范围/查询本身的旁注。如果我正确理解您的评论,您想按最低的 nonzeroudtid排序。这将是棘手的,细节将取决于您的数据库(分组,尤其是复杂的分组,是在 mySQL 与 PostGreSQL(Rails 应用程序的两个最常见的数据库)中工作方式完全不同的事情之一)。这个概念被称为“分组最大值”,您最好的选择可能是结合您的数据库名称搜索该短语。Entrowindex

于 2013-08-29T02:56:31.130 回答