我正在使用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 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
答案 0 :(得分:5)
作为@ 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
答案 1 :(得分:3)
在这种情况下,我没有得到加载错误,但是boolean_scope就是 用户和消息未定义
问题是include
在类的实例上添加方法。您需要使用extend
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
extend ScopeHelpers
end
现在您可以像User.boolean_scope
一样调用它。以下是 include vs 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>
答案 2 :(得分:2)
您的fct()
和User
类似乎没有继承Message
。他们将如何访问ApplicationRecord
?
试试这个:
::boolean_scope