# == Schema Information # # Table name: roles # # id :integer not null, primary key # access :integer default(0), not null # active :boolean default(TRUE) # created_at :datetime # updated_at :datetime # plan_id :integer # user_id :integer # # Indexes # # index_roles_on_plan_id (plan_id) # index_roles_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (plan_id => plans.id) # fk_rails_... (user_id => users.id) # class Role < ActiveRecord::Base include FlagShihTzu include ValidationMessages include ValidationValues # ============= # = Constants = # ============= # Returns a hash of hashes where each key represents an access level # (e.g. see access_level method to understand the integers) # # This method becomes useful for generating template messages (e.g. # permissions change notification mailer) ACCESS_LEVEL_MESSAGES = { 5 => { type: _('reviewer'), placeholder1: _('read the plan and provide feedback.'), placeholder2: nil }, 3 => { type: _('co-owner'), placeholder1: _('write and edit the plan in a collaborative manner.'), placeholder2: _('You can also grant rights to other collaborators.') }, 2 => { type: _('editor'), placeholder1: _('write and edit the plan in a collaborative manner.'), placeholder2: nil, }, 1 => { type: _('read-only'), placeholder1: _('read the plan and leave comments.'), placeholder2: nil, } } # ================ # = Associations = # ================ belongs_to :user belongs_to :plan ## # Define Bit Field Values # Column access has_flags 1 => :creator, # 1 2 => :administrator, # 2 3 => :editor, # 4 4 => :commenter, # 8 5 => :reviewer, # 16 column: 'access' # =============== # = Validations = # =============== validates :user, presence: { message: PRESENCE_MESSAGE } validates :plan, presence: { message: PRESENCE_MESSAGE } validates :active, inclusion: { in: BOOLEAN_VALUES, message: INCLUSION_MESSAGE } validates :access, presence: { message: PRESENCE_MESSAGE }, numericality: { greater_than: 0, only_integer: true, message: _("can't be less than zero") } # ============= # = Callbacks = # ============= # TODO: Push this down to the DB constraints after_initialize :set_defaults ## # Roles with given FlagShihTzu access flags # # flags - One or more symbols that represent access flags # # Return ActiveRecord::Relation scope :with_access_flags, -> (*flags) { bad_flag = flags.detect { |flag| !flag.in?(flag_mapping['access'].keys) } raise ArgumentError, "Unkown access flag '#{bad_flag}'" if bad_flag access_values = flags.map { |flag| sql_in_for_flag(flag.to_sym, 'access') } .flatten .uniq where(access: access_values) } # =========================== # = Public instance methods = # =========================== # The access level for the current project group: # - 5 if the user is a reviewer # - 3 if the user is an administrator # - 2 if the user is an editor # - 1 if the user can only read # used to facilliatte formtastic # # Returns Integer def access_level if self.reviewer? return 5 elsif self.administrator? return 3 elsif self.editor? return 2 elsif self.commenter? return 1 end end def access_level=(value) self.commenter = value.to_i >= 1 self.editor = value.to_i >= 2 self.administrator = value.to_i >= 3 end alias :set_access_level :access_level= deprecate :set_access_level, deprecator: Cleanup::Deprecators::SetDeprecator.new def set_defaults self.active = true if self.new_record? end end # ----------------------------------------------------- # Bitwise key # ----------------------------------------------------- # 01 - creator # 02 - administrator # 03 - creator + administrator # 04 - editor # 05 - creator + editor # 06 - administraor + editor # 07 - creator + editor + administrator # 08 - commenter # 09 - creator + commenter # 10 - administrator + commenter # 11 - creator + administrator + commenter # 12 - editor + commenter # 13 - creator + editor + commenter # 14 - administrator + editor + commenter # 15 - creator + administrator + editor + commenter # 16 - reviewer # 17 - creator + reviewer # 18 - administrator + reviewer # 19 - creator + administrator + reviewer # 20 - editor + reviewer # 21 - creator + editor + reviewer # 22 - administraor + editor + reviewer # 23 - creator + editor + administrator + reviewer # 24 - commenter + reviewer # 25 - creator + commenter + reviewer # 26 - administrator + commenter + reviewer # 27 - creator + administrator + commenter + reviewer # 28 - editor + commenter + reviewer # 29 - creator + editor + commenter + reviewer # 30 - administrator + editor + commenter + reviewer # 31 - creator + administrator + editor + commenter + reviewer