在Rails 5 Application Record类中包含一个模块 [英] Including a module in a Rails 5 Application Record class

查看:146
本文介绍了在Rails 5 Application Record类中包含一个模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Application Record来简化整个应用程序中的共享逻辑.

I am using Application Record to simplify shared logic throughout an application.

下面是一个示例,该示例为布尔值及其相反值编写范围.效果很好:

Here's an example that writes a scope for a boolean and its inverse. This works well:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.boolean_scope(attr, opposite = nil)
    scope(attr, -> { where("#{attr}": true) })
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present?
  end
end

class User < ApplicationRecord
  boolean_scope :verified, :unverified
end

class Message < ApplicationRecord
  boolean_scope :sent, :pending
end

我的Application Record类足够长,因此将其分解为各个模块并按需加载这些模块是很有意义的.

My Application Record class got long enough it made sense for me to break it up into individual modules and load those as needed.

这是我尝试的解决方案:

Here's my attempted solution:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  include ScopeHelpers
end

module ScopeHelpers
  def self.boolean_scope(attr, opposite = nil)
    scope(attr, -> { where("#{attr}": true) })
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present?
  end
end

class User < ApplicationRecord
  boolean_scope :verified, :unverified
end

class Message < ApplicationRecord
  boolean_scope :sent, :pending
end

在这种情况下,我没有得到加载错误,但是在UserMessage上未定义boolean_scope.

In this case, I don't get a load error, but boolean_scope is then undefined on User and Message.

是否有办法确保在适当的时间加载所包含的模块并可供Application Record及其继承模型使用?

Is there a way to ensure the included modules are loaded at the appropriate time and available to Application Record and its inheriting models?

我还尝试过让模型直接包含模块,但这并不能解决问题.

I've also attempted to have the models include the modules directly and that did not fix the issue.

module ScopeHelpers
  def self.boolean_scope(attr, opposite = nil)
    scope(attr, -> { where("#{attr}": true) })
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present?
  end
end

class User < ApplicationRecord
  include ScopeHelpers
  boolean_scope :verified, :unverified
end

class Message < ApplicationRecord
  include ScopeHelpers
  boolean_scope :sent, :pending
end

推荐答案

作为@Pavan答案的替代方法,您可以执行以下操作:

As an alternative to @Pavan's answer, you can do this:

module ScopeHelpers
  extend ActiveSupport::Concern # to handle ClassMethods submodule

  module ClassMethods
    def boolean_scope(attr, opposite = nil)
      scope(attr, -> { where(attr => true) })
      scope(opposite, -> { where(attr => false) }) if opposite.present?
    end
  end
end

# then use it as usual
class ApplicationRecord < ActiveRecord::Base
  include ScopeHelpers
  ...
end

这篇关于在Rails 5 Application Record类中包含一个模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆