我正在尝试在我在rails应用程序中构建的一些表中实现可排序列。
我有两个不同的模型。一个是“投注”:
class Bet < ApplicationRecord
validates :title, presence: true, length: { maximum: 50 }
validates :benchmark, presence: true
has_many :picks, dependent: :destroy
end
另一个是“Picks”,属于两个资源,用户和投注(上图)。
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 and Picks都有一个“Benchmark”值,这是一个浮点数。
当我进入rails console并调用此命令时:
@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”DESC。
我在这里缺少什么?
答案 0 :(得分:0)
您看到的问题是由default_scope
模型的Pick
造成的。这将使所有默认查询都使用该范围。正如您在生成的SQL中看到的那样,它首先按created_at desc
排序,然后是您使用的任何其他订单属性。
默认范围一直被认为是rails中的反模式,因为它会导致您所看到的问题。有两种方法可以解决这个问题。
1)如果您不确定在代码库中使用此默认作用域的位置,您可能希望保留它。要绕过默认范围,请使用unscoped将其从您正在进行的当前查询中删除。
@picks = Pick.all.unscoped.order("benchmark")
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