[英]Rails order records by column and custom method
對於我的其中一個模型,我試圖設置一個按年份和季節排序的默認范圍。 由於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
字段的值強制為整數,然后使用該值對記錄進行排序。 請參見以下答案以獲取示例:
SQL:ORDER BY在特定列中使用子字符串...可能嗎?
更好的方法是將季節以整數而不是字符串的形式存儲在數據庫中。 最簡單的方法是在Rails 4.1+中使用ActiveRecord::Enum
。 在模型中添加以下內容:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.