动态定义 class 和实例方法
Define class and instance methods dynamically in concern
我有一个问题:
# app/models/concerns/rolable.rb
module Rolable
extend ActiveSupport::Concern
included do
rolify
Role.find_each do |role|
scope "#{role.name.pluralize}", -> { joins(:roles).where(roles: {name: send("#{role.name}_role_name")}).distinct }
end
end
class_methods do
Role.find_each do |role|
define_method "#{role.name}_role_name" do
role.name
end
define_method "#{role.name}_role_id" do
role.id
end
end
end
Role.find_each do |role|
define_method("#{role.name}?") do
has_role? self.class.send("#{role.name}_role_name")
end
end
end
如您所见,它定义了一堆作用域、class 方法和实例方法。但我对 Role.find_each do |role| ... end
.
的重复感到不高兴
如何消除这种重复?我试过这个
Role.find_each do |role|
included do
...
end
class_methods do
...
end
end
但由于多个 included
块,它不起作用。
我可以在方法中提取Role.find_each
,但也好不到哪里去。
如何改进此代码并消除重复?
我认为你的逻辑很糟糕。您不应该使用 Role.find_each
,因为在初始化您的基础 class 后新角色将不可用,否则您每次需要时都必须明确加载您的关注点。
在rolify中你有一些有用的方法:
Forum.with_role(:admin)
Forum.with_role(:admin, current_user)
@user.has_role?(:forum, Forum)
...
如果您非常确定您的角色清单不会增加,那么也许您可以动态定义一堆匿名关注点,而不是为所有角色创建一个关注点。
# models/concerns/rolables.rb
# no need to call `find_each' because the number or roles will never exceed 1000
Rolables = Role.all.map do |role|
Module.new do
extend ActiveSupport::Concern
included do
scope "#{role.name.pluralize}", -> { joins(:roles).where(roles: {name: send("#{role.name}_role_name")}).distinct }
define_method("#{role.name}?") do
has_role? self.class.send("#{role.name}_role_name")
end
end
class_methods do
define_method "#{role.name}_role_name" do
role.name
end
define_method "#{role.name}_role_id" do
role.id
end
end
end
end
并将所有这些问题纳入您的模型:
# models/user.rb
class User
Rolables.each{|concern| include concern}
end
我有一个问题:
# app/models/concerns/rolable.rb
module Rolable
extend ActiveSupport::Concern
included do
rolify
Role.find_each do |role|
scope "#{role.name.pluralize}", -> { joins(:roles).where(roles: {name: send("#{role.name}_role_name")}).distinct }
end
end
class_methods do
Role.find_each do |role|
define_method "#{role.name}_role_name" do
role.name
end
define_method "#{role.name}_role_id" do
role.id
end
end
end
Role.find_each do |role|
define_method("#{role.name}?") do
has_role? self.class.send("#{role.name}_role_name")
end
end
end
如您所见,它定义了一堆作用域、class 方法和实例方法。但我对 Role.find_each do |role| ... end
.
如何消除这种重复?我试过这个
Role.find_each do |role|
included do
...
end
class_methods do
...
end
end
但由于多个 included
块,它不起作用。
我可以在方法中提取Role.find_each
,但也好不到哪里去。
如何改进此代码并消除重复?
我认为你的逻辑很糟糕。您不应该使用 Role.find_each
,因为在初始化您的基础 class 后新角色将不可用,否则您每次需要时都必须明确加载您的关注点。
在rolify中你有一些有用的方法:
Forum.with_role(:admin)
Forum.with_role(:admin, current_user)
@user.has_role?(:forum, Forum)
...
如果您非常确定您的角色清单不会增加,那么也许您可以动态定义一堆匿名关注点,而不是为所有角色创建一个关注点。
# models/concerns/rolables.rb
# no need to call `find_each' because the number or roles will never exceed 1000
Rolables = Role.all.map do |role|
Module.new do
extend ActiveSupport::Concern
included do
scope "#{role.name.pluralize}", -> { joins(:roles).where(roles: {name: send("#{role.name}_role_name")}).distinct }
define_method("#{role.name}?") do
has_role? self.class.send("#{role.name}_role_name")
end
end
class_methods do
define_method "#{role.name}_role_name" do
role.name
end
define_method "#{role.name}_role_id" do
role.id
end
end
end
end
并将所有这些问题纳入您的模型:
# models/user.rb
class User
Rolables.each{|concern| include concern}
end