2017-10-10 38 views
0

我試圖在一些表格中實現可排序的列,我在建立一個Rails應用程序。Rails ORDER BY的工作方式有所不同,具體取決於型號

我有兩個不同的模型。一種是「投注」:

class Bet < ApplicationRecord 
    validates :title, presence: true, length: { maximum: 50 } 
    validates :benchmark, presence: true 
    has_many :picks, dependent: :destroy 
end 

另一種是「挑選」,屬於兩種資源,用戶和投注(上圖)。

class Pick < ApplicationRecord 
    belongs_to :user 
    belongs_to :bet 
    default_scope -> { order(created_at: :desc) } 
    validates :user_id, presence: true 
    validates :bet_id, presence: true 
end 

投注和選擇都有一個「基準」值,這是一個浮動。

當我去軌控制檯,並調用這個命令:

@bets = Bet.all.order("benchmark") 

我得到:

Bet Load (0.6ms) SELECT "bets".* FROM "bets" ORDER BY benchmark LIMIT ? [["LIMIT", 11]] 

這就是我想要的。如果我打印出所有@bets的基準,他們會按順序打印。

然而,當我做選秀權同樣的事情,我得到這個:

@picks = Pick.all.order("benchmark") 

Pick Load (1.2ms) SELECT "picks".* FROM "picks" **ORDER BY "picks"."created_at" DESC**, benchmark LIMIT ? [["LIMIT", 11]] 

不管我做什麼,它只會通過「選秀」「created_at」倒序的選秀權。

我在這裏錯過了什麼?

+1

我想我只是意識到更換其來自:default_scope - > {順序(created_at:DESC)}。如果我刪除這個,我可以期待什麼樣的反應在程序中? –

+0

這取決於您的應用程序的大小和測試覆蓋率,但通常刪除'default_scope'是一個很大的重構因爲有許多未經測試的行爲依賴關係。檢查並查看'reorder'方法是否能完成你所需要的。 –

回答

0

您所看到的問題歸因於您爲Pick模型設置的default_scope。這將使所有默認查詢使用該範圍。正如您在生成的SQL中看到的那樣,它首先按created_at desc排序,然後按照您使用的任何其他順序屬性進行排序。

默認範圍一直被認爲是rails中的反模式,因爲它會導致類似於您所看到的問題。有兩種方法可以解決這個問題。

1)如果您不確定代碼庫中這個默認範圍的使用情況,您可能需要保留它。要繞過默認範圍,請使用unscoped將其從當前查詢中刪除。 2)如果您目前沒有在任何地方使用該默認範圍,則可以使用該範圍。從類中刪除它,然後用常規scope

class Pick < ApplicationRecord 
    belongs_to :user 
    belongs_to :bet 
    scope :order_newest -> { order(created_at: :desc) } 
    validates :user_id, presence: true 
    validates :bet_id, presence: true 
end 

# Use like this 
@picks = Pick.all.order_newest 
相關問題