Я использую код пространства имен в приложении в качестве упражнения. И под «упражнением» я подразумеваю полностью для развлечения. Предположим, что примеры ролей Performer
и Manager
представляют 2 из 20 ролей, которые должны быть определены вместе с вспомогательными методами.
class Role
module Performer
extend ActiveSupport::Concern
module InstanceMethods
def performer?(id = @current_user_id)
true unless self.roles.where(user_id: id, name: 'Performer').empty?
end
def make_performer(id = @current_user_id)
self.roles.new(user_id: id, name: 'Performer')
end
end
end
module Manager
extend ActiveSupport::Concern
module InstanceMethods
def manager?(id = @current_user_id)
true unless self.roles.where(user_id: id, name: 'Manager').empty?
end
def make_manager(id = @current_user_id)
self.roles.new(user_id: id, name: 'Manager')
end
end
end
end
При необходимости выбранные роли смешиваются с другими модулями. Различный набор ролей смешан в каждом модуле,
class Group
module Roles
extend ActiveSupport::Concern
included do
include Role::Manager
include Role::Performer
before_create :make_creator_manager
protected
def make_creator_manager
make_manager @current_user_id if @current_user_id
end
end
end
end
и затем связаны с отдельной моделью полиморфной ассоциацией.
class Group < ActiveRecord::Base
include Group::Roles
attr_accessor :current_user_id
has_many :roles, as: :restrictable
end
Я мог бы высушить содержимое методов с помощью замыканий, но поскольку имена методов также следуют шаблону, будет ли метапрограммирование более логичным? Пример ruby
Достаточно ли распространено метапрограммирование в ruby, чтобы тот, кто (теоретически) возглавил этот проект, мог без труда поддерживать его?
Редактировать 1: Миграция ролей может иметь отношение к этому обсуждению
class CreateRoles < ActiveRecord::Migration
def change
create_table :roles do |t|
t.belongs_to :user
t.references :restrictable, polymorphic: true
t.string :name
t.timestamps
end
add_index :roles, :user_id
add_index :roles, [:restrictable_id, :restrictable_type]
end
end