问题描述
我正在使用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
在这种情况下,我没有得到加载错误,但是在User
和Message
上未定义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类中包含一个模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!