Rails Active Record查找(:all,:order =>)问题


76

我似乎无法一次使用ActiveRecord :: Base.find选项:order多个列。

例如,我有一个带有日期和出席列的“显示”模型。

如果我运行以下代码:

@shows = Show.find(:all, :order => "date")

我得到以下结果:

[#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 1, date: "2009-04-18", attending: 78>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

如果我运行以下代码:

@shows = Show.find(:all, :order => "attending DESC")

[#<Show id: 4, date: "2009-04-21", attending: 136>,
 #<Show id: 2, date: "2009-04-19", attending: 91>,
 #<Show id: 1, date: "2009-04-18", attending: 78>,
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 7, date: "2009-04-18", attending: 2>]

但是,如果我运行:

@shows = Show.find(:all, :order => "date, attending DESC")

要么

@shows = Show.find(:all, :order => "date, attending ASC")

要么

@shows = Show.find(:all, :order => "date ASC, attending DESC")

我得到的结果与仅按日期排序的结果相同:

 [#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 1, date: "2009-04-18", attending: 78>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

在哪里,我想得到这些结果:

[#<Show id: 1, date: "2009-04-18", attending: 78>,
#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

这是从日志生成的查询:

[4;35;1mUser Load (0.6ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 1) LIMIT 1[0m
[4;36;1mShow Load (3.0ms)[0m   [0;1mSELECT * FROM "shows" ORDER BY date ASC, attending DESC[0m
[4;35;1mUser Load (0.6ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 1) [0m

最后,这是我的模型:

  create_table "shows", :force => true do |t|
    t.string   "headliner"
    t.string   "openers"
    t.string   "venue"
    t.date     "date"
    t.text     "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.decimal  "price"
    t.time     "showtime"
    t.integer  "attending",   :default => 0
    t.string   "time"
  end

我想念什么?我究竟做错了什么?

更新:感谢您的所有帮助,但似乎所有人都和我一样受挫。解决问题的实际上是切换数据库。我从默认的sqlite3切换到mysql。


我目前没有Rails设置来检查您的代码;这两个命令正在生成什么查询?您应该能够检查/ logs中的日志以查看。
YenTheFirst

查询确实会非常有帮助
aivarsak

可能无关紧要,但是您使用的是哪个版本的AR,以及哪个DB?
Mike Woodhouse

[4; 35; 1m用户负载(0.6ms)[0m [0mSELECT *来自“用户”,其中(“用户”。“ id” = 1)LIMIT 1 [0m [4; 36; 1m显示负载(3.0ms)[0m [ 0; 1mSELECT * FROM“显示”按日期ASC排序,参加DESC [0m [4; 35; 1m用户负载(0.6ms)[0m [0mSELECT * FROM“用户”,其中(“用户”。“ id” = 1)[ 0m
CodingWithoutComments

我正在使用sqllite3和rails版本2.2.2
CodingWithoutComments,2009年

Answers:


35

我注意到在您的第一个示例中,简单的:order =>“ date”记录7在记录1之前排序。无论您是否按出席方式排序,此顺序也是您如何在多列排序中查看结果的方式。

如果日期不完全相同,并且7的日期早于1的日期,这对我来说似乎很有意义。该查询没有发现日期s完全相等,而是通过出席进行排序,而是发现日期不相等,并且像所有其他记录一样按日期进行排序。

通过浏览,我发现SQLite对DATE或DATETIME数据类型没有本机的了解,而是为用户提供了必须自己解析的浮点数或文本的选择。数据库中日期的文字表示是否可能不完全相等?大多数人似乎需要使用日期函数,以便日期的行为与您期望的一样。也许有一种用date函数按列包装订单的方法,该函数将为您提供一些具体的比较对象,例如date(date)ASC参加DESC。我不确定语法是否有效,但这是解决您的问题的一个领域。希望能有所帮助。


这是有道理的- DATE列实际上可能是一个DATETIME或一些其他的小数部分-所以你不得不为了通过日期部分......是啊......良好的渔获物
马特Rogish

4
我将数据库从sqlite3切换到mysql。这使问题消失了。
CodingWithoutComments

46

可能是两件事。第一,

此代码已弃用:

Model.find(:all, :order => ...)

应该:

Model.order(...).all

:all,:order和许多其他选项不再支持查找。

其次,你可能有这是执行一些命令你叫前default_scopefindShow

经过数小时的互联网浏览,我找到了一些有用的文章来解释这个问题:


1
Model.all(:order => ...)很好
mdpatrick

Model.order(...)更好
Yule 2015年

在rails 4.1中,Model.all(:order =>“ field_name ASC”)给出了错误的参数数量(1代表0)错误。Model.order(“ field_name ASC”)不会。在升级旧应用程序时发现了这一点。
Mark Davies


4

我只是遇到了同样的问题,但是我设法使查询在SQLite中像这样工作:

@shows = Show.order("datetime(date) ASC, attending DESC")

我希望这可以帮助某人节省一些时间



3

确保直接在数据库级别检查架构。之前,我对此非常着迷,例如,最初编写迁移来创建:datetime列,然后在本地运行它,然后在实际部署之前将迁移调整为:date。因此,除了我的人以外,每个人的数据库看起来都很不错,并且这些错误是微妙的。


2

我知道为什么Rails开发人员使用sqlite3进行开箱即用的实现,但是MySQL更加实用,恕我直言。我知道这取决于您要构建Rails应用程序的目的,但是大多数人会将默认的database.yml文件从sqlite3切换到MySQL。

很高兴您解决了您的问题。


完全同意。使用将要部署的相同数据库进行开发。从长远来看,它将为您节省许多麻烦。
英国

2

找到解决方案是一件好事。但这是一个有趣的问题。我直接使用sqlite3尝试了此操作(不通过导轨),但没有得到相同的结果,对我来说,订单出乎意料了。

如果您想继续研究这个问题,我建议您做的是启动sqlite3命令行应用程序并检查架构和那里的查询:

这显示了架构: .schema

然后只要运行select语句,它就会出现在日志文件中: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

这样,您可以查看是否:

  1. 模式看起来像您想要的(该日期实际上是一个日期)
  2. 日期列实际上包含一个日期,而不是一个时间戳(也就是说,您没有一天中的某个时间来弄乱排序)


0

我正在使用Rails 6,并且Model.all(:order'columnName DESC')无法正常工作。我在OrderInRails中找到了正确的答案

这很简单。

@variable=Model.order('columnName DESC')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.