在 Rails 5 申请记录中包含一个模块 class
Including a module in a Rails 5 Application Record class
我正在使用 Application Record 来简化整个应用程序的共享逻辑。
这是一个为布尔值及其逆函数编写作用域的示例。这很好用:
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
我的申请记录 class 足够长,我可以将其分解成单独的模块并根据需要加载它们。
这是我尝试的解决方案:
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
在这种情况下,我没有收到加载错误,但是 boolean_scope
在 User
和 Message
.
上未定义
有没有办法确保包含的模块在适当的时间加载并可供 Application Record 及其继承模型使用?
我也曾尝试让模型直接包含模块,但这并没有解决问题。
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
您的 User
和 Message
类 似乎没有继承 ApplicationRecord
。他们将如何访问 ::boolean_scope
?
试试这个:
class User < ApplicationRecord
boolean_scope :verified, :unverified
end
class Message < ApplicationRecord
boolean_scope :sent, :pending
end
In this case, I don't get a load error, but boolean_scope is then
undefined on User and Message
问题是 include
在 class 的 实例上添加方法。您需要使用 extend
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
extend ScopeHelpers
end
现在您可以像 User.boolean_scope
那样称呼它了。以下是 include 与 extend
的示例
module Foo
def foo
puts 'heyyyyoooo!'
end
end
class Bar
include Foo
end
Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class
class Baz
extend Foo
end
Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>
作为@Pavan 答案的替代方案,您可以这样做:
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
我正在使用 Application Record 来简化整个应用程序的共享逻辑。
这是一个为布尔值及其逆函数编写作用域的示例。这很好用:
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
我的申请记录 class 足够长,我可以将其分解成单独的模块并根据需要加载它们。
这是我尝试的解决方案:
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
在这种情况下,我没有收到加载错误,但是 boolean_scope
在 User
和 Message
.
有没有办法确保包含的模块在适当的时间加载并可供 Application Record 及其继承模型使用?
我也曾尝试让模型直接包含模块,但这并没有解决问题。
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
您的 User
和 Message
类 似乎没有继承 ApplicationRecord
。他们将如何访问 ::boolean_scope
?
试试这个:
class User < ApplicationRecord
boolean_scope :verified, :unverified
end
class Message < ApplicationRecord
boolean_scope :sent, :pending
end
In this case, I don't get a load error, but boolean_scope is then undefined on User and Message
问题是 include
在 class 的 实例上添加方法。您需要使用 extend
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
extend ScopeHelpers
end
现在您可以像 User.boolean_scope
那样称呼它了。以下是 include 与 extend
module Foo
def foo
puts 'heyyyyoooo!'
end
end
class Bar
include Foo
end
Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class
class Baz
extend Foo
end
Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>
作为@Pavan 答案的替代方案,您可以这样做:
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