【问题标题】:Rails sorting gemRails 分拣宝石
【发布时间】:2016-01-13 22:07:34
【问题描述】:

我想创建一个可以修改 ActiveRecord::Base select 方法的 gem。例如,当我包含我的 gem 并输入:

Somemodel.all

它应该像往常一样返回一个按 id 排序的数组,但按降序而不是升序。我不知道它应该是什么样子。我不想创建其他方法,例如:

Somemodel.where(name: "John").revert_it

但只需这样做:

Somemodel.where(name: "John")

我想知道修改ActiveRecord::Base 方法,但这没有任何意义。 IMO 最好的方法是在每个 ActiveRecord::Base 方法之后回调。

【问题讨论】:

  • 我会创建其他方法。无论谁在你之后进来并且无法弄清楚为什么顺序被颠倒,这真的会让你感到困惑。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

不建议修改任何核心 ActiveRecord 方法(除非您有充分的理由),因为这会在未来造成很多混乱。

即使您正在考虑修改 select ,您也必须确保始终返回一个 ActiveRecord relation ,以便它可以作为标准方式链接,

对于您的示例,AR 已经有一个方法

User.all.reverse

【讨论】:

  • 用英文写作时请使用英文标点。
  • User.all.reverse_order 可能效率更高一些(让 DB 以相反的顺序返回它们,而不是获取数组并反转它)
  • @sawa,抱歉.. 不是以英语为母语的人 :)
【解决方案2】:

你可以使用ActiveRecord方法default_scope来实现这个:

class MyModel < ActiveRecord::Base

  default_scope { order("id DESC") }

end

MyModel.all
# => SELECT * FROM my_models ORDER BY id DESC

【讨论】:

  • 你就是这个主意!但我需要它作为模块
  • 你就是这个主意!但我需要它作为模块 - mike927 1 小时前 @mike927 很好,你可以很容易地制作这个模块 ARExtension; extend ActiveSupport::Concern; module ClassMethods;default_scope { order("id DESC") };end; end; ActiveRecord.Base.send(:include,ARExtension) 这将把默认范围添加到从 AR Base 继承的所有对象中,并且不会覆盖默认范围。跨度>
【解决方案3】:

我得到了完全有效的答案:

  def self.included(base)
    base.class_eval do
     default_scope { order(id: 'desc') }
    end
  end

上面的方法应该在某个模块中,然后模块包含在某个模型类中

【讨论】:

  • 虽然我不鼓励这样做,因为其他人都提到了同样的原因,请参阅我对@Drenmi 帖子的评论,了解将这个添加到 ActiveRecord 的正确方法。
  • 感谢您的回答。我会考虑的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多