在模型中我有:
default_scope -> { order(created_at: :desc) }
scope :ascending, -> { order(created_at: :asc) }
在视图中:
<ol class="notices comments">
<%= render notice.comments.ascending %>
</ol>
在模型中,当我将default_scope -> { order(created_at: :desc) }
更改为default_scope -> { order(created_at: :asc) }
时,通知会按预期响应并按升序显示而不是降序。但是,当我将scope :ascending, -> { order(created_at: :asc) }
更改为scope :ascending, -> { order(created_at: :desc) }
时,它不会改变任何内容。代码有什么问题?
答案 0 :(得分:1)
当您调用order
时,它只是向ORDER BY子句添加了另一个组件。因此,如果您有默认范围并添加ascending
范围,则最终会得到此ORDER BY:
ORDER BY created_at desc, created_at asc
created_at asc
被有效忽略,因为不太可能与created_at desc
排序有任何关系。
您可能希望在范围内使用reorder
来完全替换ORDER BY:
scope :ascending, -> { reorder(created_at: :asc) }
这假设唯一有效的排序来自默认范围,因此如果您说出以下内容会导致意外:
Model.order(:whatever).ascending
范围将删除order(:whatever)
。
我倾向于认为默认范围几乎总是一个坏主意,因为它们隐藏了你的东西,当默认范围包括ORDER BY调整时,这是双倍的。我删除了默认范围,并让调用者明确指定他们的顺序。