通过模块共享范围?

发布于 2024-12-03 00:02:44 字数 372 浏览 1 评论 0原文

我想通过将共享范围移动到模块中来干燥多个模型,例如:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
  end
end

我还想创建测试模块的共享规范。不幸的是,当我尝试将共享范围包含在我的模型中时,我得到:

undefined method `order' for CommonScopes::ClassMethods:Module

有什么想法吗?谢谢!

I want to DRY up several models by moving shared scopes into a module, something like:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
  end
end

I also want to create shared specs that test the module. Unfortunately when I try to include the shared scope in my model I get:

undefined method `order' for CommonScopes::ClassMethods:Module

Any ideas? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅忆流年 2024-12-10 00:02:44

与 Rails 4 中一样,您可以简单地使用 lambda 来延迟代码的执行(适用于 Rails 3)也):

module CommonScopes
  extend ActiveSupport::Concern

  included do
    scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
  end
end

As in rails 4 scope syntax you can simply use a lambda to delay the execution of the code (works in rails 3 too):

module CommonScopes
  extend ActiveSupport::Concern

  included do
    scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
  end
end
じее 2024-12-10 00:02:44

您可以使用 instance_eval

module CommonScopes
  extend ActiveSupport::Concern

  def self.included(klass)
    klass.instance_eval do
      scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
    end
  end
end

You can use instance_eval

module CommonScopes
  extend ActiveSupport::Concern

  def self.included(klass)
    klass.instance_eval do
      scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
    end
  end
end
迷乱花海 2024-12-10 00:02:44

因为当您的模块被 Ruby 解析时,您的 scope 方法会立即被调用,并且无法从您的 CommonScopes 模块访问它。

但是您可以用类方法替换您的作用域调用:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    def ordered_for_display
      order("#{self.to_s.tableize}.rank asc")
     end
  end
end

Because your scope method is called immediately when your module is parsed by Ruby and it's not accessible from your CommonScopes module..

But you can replace your scope call by a class method:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    def ordered_for_display
      order("#{self.to_s.tableize}.rank asc")
     end
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文