Rails Activerecord找到(:all,:order =>)问题

时间:2009-04-13 00:25:31

标签: ruby-on-rails ruby activerecord

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

例如,我有一个“显示”模型,其中包含日期和参加列。

如果我运行以下代码:

@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")

OR

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

OR

@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。

10 个答案:

答案 0 :(得分:45)

可能是两件事。首先,

不推荐使用此代码:

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

应该是:

Model.order(...).all

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

其次,find上调用Show之前,您可能有一个执行某些排序的default_scope。

在网上挖掘时间让我得到了一些解释这个问题的有用文章:

答案 1 :(得分:36)

我注意到在你的第一个例子中,简单的:order =&gt; “日期”,记录 7 在记录 1 之前排序。此顺序也是您在多列排序中查看结果的方式,无论您是否按参加排序。

如果日期不完全相同,并且 7 的日期早于 1 的日期,这似乎对我有意义。而不是发现日期完全相同,然后继续按参加排序,查询发现日期不相等,只是像所有其他记录一样排序

我从浏览中看到,SQLite没有对DATE或DATETIME数据类型的本地理解,而是让用户可以选择他们必须自己解析的浮点数或文本。数据库中日期的文字表示可能不完全相等吗?大多数人似乎需要use date functions,以便日期表现得像您期望的那样。也许有一种方法可以用date function按列包装您的订单,这将为您提供具体的比较内容,例如日期(日期)ASC,参加DESC 。我不确定语法是否有效,但这是解决问题的一个方面。希望有所帮助。

答案 2 :(得分:14)

问题是 date 保留的sqlite3关键字。我有一个类似的问题 time ,也是一个保留关键字,在PostgreSQL中运行良好,但在sqlite3中运行不正常。 解决方案是重命名列

请参阅:Sqlite3 activerecord :order => "time DESC" doesn't sort

答案 3 :(得分:4)

我遇到了同样的问题,但我设法让我的查询在SQLite中运行如下:

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

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

答案 4 :(得分:3)

不仅仅是:order => 'column1 ASC, column2 DESC'

答案 5 :(得分:3)

确保直接在数据库级别检查架构。我之前已经被烧过了,例如,最初编写了一个迁移来创建一个:datetime列,我在本地运行它,然后在实际部署之前将迁移调整到:date。因此,每个人的数据库看起来都很好,除了我的,并且错误是微妙的。

答案 6 :(得分:2)

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

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

答案 7 :(得分:2)

你找到了解决方案是件好事。但这是一个有趣的问题。 我直接用sqlite3尝试了它(没有通过rails)并没有得到相同的结果,对我来说订单按预期出现。

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

这会显示架构:.schema

然后只运行日志文件中显示的select语句:SELECT * FROM "shows" ORDER BY date ASC, attending DESC

通过这种方式,您可以看到:

  1. 架构看起来如您所愿(该日期实际上是日期)
  2. 日期列实际上包含一个日期,而不是一个时间戳(也就是说,你没有一天的时间会弄乱排序)

答案 8 :(得分:1)

我正在使用rails 6,并且Model.all(:order'columnName DESC')无法正常工作。我在OrderInRails

中找到了正确答案

这很简单。

@variable=Model.order('columnName DESC')

答案 9 :(得分:0)

这也可能有所帮助:

Post.order(created_at: :desc)