【问题标题】:Rails order records by column and custom methodRails 按列和自定义方法的订单记录
【发布时间】:2014-04-19 00:46:26
【问题描述】:

对于我的一个模型,我正在尝试设置一个按年份和季节排序的默认范围。由于 year 是一个整数,因此很容易按此排序。我的麻烦是按季节订购(如果年份相同)。这里只是按年份排序:

class League < ActiveRecord::Base
  def self.default_scope
    order(:year)
  end

  # The season's that are allowed to be used
  # This is also the order I'd like to use
  def self.season_collection
    {
      "Spring" => "Spring",
      "Summer" => "Summer",
      "Fall"   => "Fall"
    }
  end
end

如果我尝试order(:year, :season),那么它将按字母顺序进行。有没有办法使用order(所以在数据库端完成)?

【问题讨论】:

  • 数据库中的季节是什么类型?细绳?你想尊重你在 season_collection 中定义的散列顺序吗?我的意思是,先是春天,然后是夏天..
  • 是的,抱歉,不清楚。季节是一个字符串,我希望它们按那个顺序排列(“Spring”、“Summer”、“Fall”)

标签: ruby-on-rails activerecord ruby-on-rails-4


【解决方案1】:

您可以在数据库中对它们进行排序,但这不会非常有效,因为您需要将season 字段的值强制转换为整数,然后使用它来对记录进行排序。请参阅此答案以获取示例:

SQL: ORDER BY using a substring within a specific column... possible?

更好的方法是将季节作为整数而不是字符串存储在数据库中。使用它的最简单方法是 ActiveRecord::Enum 在 Rails 4.1+ 中可用。在您的模型中添加:

class League < ActiveRecord::Base
  enum season: %w{Spring Summer Autumn Winter}
end

然后你可以像这样创建记录:

0> league1 = League.create!(season: 'Summer')
=> #<League id: 1>
1> league2 = League.create!(season: 'Spring')
=> #<League id: 2>
2> league3 = League.create!(season: 'Autumn')
=> #<League id: 3>
3> league3.season
=> "Autumn"

实际上,ActiveRecord 不存储字符串,而是一个引用它的整数。您可以找到以下整数:

4> League.seasons
=> {"Spring"=>0, "Summer"=>1, "Autumn"=>2, "Winter"=>3}

要让它们按顺序排列,只需对字段进行排序:

5> League.order(:season)
SELECT * FROM leagues ORDER BY season
=> #<ActiveRecord::Relation [#<League id: 2>, #<League id: 1>, #<League id: 3>]>

如果要查询特定季节,ActiveRecord 会自动将名称映射到 ID:

6> League.where(season: 'Summer')
SELECT * FROM leagues WHERE season = 1
=> #<ActiveRecord::Relation [#<League id: 1>]>

如果您尝试设置无效季节,ActiveRecord 会通知您:

7> league3.season = 'Tomato'
ArgumentError: 'Tomato' is not a valid season

【讨论】:

    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 2013-01-09
    • 2016-06-18
    • 2013-11-05
    • 2011-09-08
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多