Class: Member

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/member.rb

Overview

Redmine - project management software Copyright (C) 2006-2021 Jean-Philippe Lang

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create_principal_memberships(principal, attributes) ⇒ Object

Creates memberships for principal with the attributes, or add the roles if the membership already exists.

  • project_ids : one or more project ids

  • role_ids : ids of the roles to give to each membership

Example:

Member.create_principal_memberships(user, :project_ids => [2, 5], :role_ids => [1, 3]

205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'app/models/member.rb', line 205

def self.create_principal_memberships(principal, attributes)
  members = []
  if attributes
    project_ids = Array.wrap(attributes[:project_ids] || attributes[:project_id])
    role_ids = Array.wrap(attributes[:role_ids])
    project_ids.each do |project_id|
      member = Member.find_or_new(project_id, principal)
      member.role_ids |= role_ids
      member.save
      members << member
    end
  end
  members
end

.find_or_new(project, principal) ⇒ Object

Finds or initializes a Member for the given project and principal


221
222
223
224
225
226
227
228
# File 'app/models/member.rb', line 221

def self.find_or_new(project, principal)
  project_id = project.is_a?(Project) ? project.id : project
  principal_id = principal.is_a?(Principal) ? principal.id : principal

  member = Member.find_by_project_id_and_user_id(project_id, principal_id)
  member ||= Member.new(:project_id => project_id, :user_id => principal_id)
  member
end

Instance Method Details

#<=>(member) ⇒ Object


83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/models/member.rb', line 83

def <=>(member)
  a, b = roles.sort, member.roles.sort
  if a == b
    if principal
      principal <=> member.principal
    else
      1
    end
  elsif a.any?
    b.any? ? a <=> b : -1
  else
    1
  end
end

#any_inherited_role?Boolean

Returns true if one of the member roles is inherited

Returns:

  • (Boolean)

109
110
111
# File 'app/models/member.rb', line 109

def any_inherited_role?
  member_roles.any? {|mr| mr.inherited_from}
end

#base_reloadObject


47
# File 'app/models/member.rb', line 47

alias :base_reload :reload

#base_role_ids=Object


63
# File 'app/models/member.rb', line 63

alias :base_role_ids= :role_ids=

#deletable?(user = User.current) ⇒ Boolean

Returns true if the member is deletable by user

Returns:

  • (Boolean)

138
139
140
141
142
143
144
# File 'app/models/member.rb', line 138

def deletable?(user=User.current)
  if any_inherited_role?
    false
  else
    roles & user.managed_roles(project) == roles
  end
end

#destroyObject

Destroys the member


147
148
149
150
# File 'app/models/member.rb', line 147

def destroy
  member_roles.reload.each(&:destroy_without_member_removal)
  super
end

#has_inherited_role?(role) ⇒ Boolean

Returns true if the member has the role and if it's inherited

Returns:

  • (Boolean)

114
115
116
# File 'app/models/member.rb', line 114

def has_inherited_role?(role)
  member_roles.any? {|mr| mr.role_id == role.id && mr.inherited_from.present?}
end

#include?(user) ⇒ Boolean

Returns true if the member is user or is a group that includes user

Returns:

  • (Boolean)

154
155
156
157
158
159
160
# File 'app/models/member.rb', line 154

def include?(user)
  if principal.is_a?(Group)
    !user.nil? && user.groups.include?(principal)
  else
    self.principal == user
  end
end

#managed_rolesObject

Returns the roles that the member is allowed to manage in the project the member belongs to


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'app/models/member.rb', line 179

def managed_roles
  @managed_roles ||= begin
    if principal.try(:admin?)
      Role.givable.to_a
    else
      members_management_roles = roles.select do |role|
        role.has_permission?(:manage_members)
      end
      if members_management_roles.empty?
        []
      elsif members_management_roles.any?(&:all_roles_managed?)
        Role.givable.to_a
      else
        members_management_roles.map(&:managed_roles).reduce(&:|)
      end
    end
  end
end

#nameObject


59
60
61
# File 'app/models/member.rb', line 59

def name
  self.user.name
end

#reload(*args) ⇒ Object


48
49
50
51
# File 'app/models/member.rb', line 48

def reload(*args)
  @managed_roles = nil
  base_reload(*args)
end

#remove_from_project_default_assigned_toObject


170
171
172
173
174
175
# File 'app/models/member.rb', line 170

def remove_from_project_default_assigned_to
  if user_id && project && project.default_assigned_to_id == user_id
    # remove project based auto assignments for this member
    project.update_column(:default_assigned_to_id, nil)
  end
end

#roleObject


53
54
# File 'app/models/member.rb', line 53

def role
end

#role=Object


56
57
# File 'app/models/member.rb', line 56

def role=
end

#role_editable?(role, user = User.current) ⇒ Boolean

Returns true if the member's role is editable by user

Returns:

  • (Boolean)

129
130
131
132
133
134
135
# File 'app/models/member.rb', line 129

def role_editable?(role, user=User.current)
  if has_inherited_role?(role)
    false
  else
    user.managed_roles(project).include?(role)
  end
end

#role_ids=(arg) ⇒ Object


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/member.rb', line 64

def role_ids=(arg)
  ids = (arg || []).collect(&:to_i) - [0]
  # Keep inherited roles
  ids += member_roles.select {|mr| !mr.inherited_from.nil?}.collect(&:role_id)

  new_role_ids = ids - role_ids
  # Add new roles
  new_role_ids.each do |id|
    member_roles << MemberRole.new(:role_id => id, :member => self)
  end
  # Remove roles (Rails' #role_ids= will not trigger MemberRole#on_destroy)
  member_roles_to_destroy = member_roles.select {|mr| !ids.include?(mr.role_id)}
  if member_roles_to_destroy.any?
    member_roles_to_destroy.each(&:destroy)
  end
  member_roles.reload
  super(ids)
end

#role_inheritance(role) ⇒ Object

Returns an Array of Project and/or Group from which the given role was inherited, or an empty Array if the role was not inherited


120
121
122
123
124
125
126
# File 'app/models/member.rb', line 120

def role_inheritance(role)
  member_roles.
    select {|mr| mr.role_id == role.id && mr.inherited_from.present?}.
    map {|mr| mr.inherited_from_member_role.try(:member)}.
    compact.
    map {|m| m.project == project ? m.principal : m.project}
end

#set_editable_role_ids(ids, user = User.current) ⇒ Object

Set member role ids ignoring any change to roles that user is not allowed to manage


100
101
102
103
104
105
106
# File 'app/models/member.rb', line 100

def set_editable_role_ids(ids, user=User.current)
  ids = (ids || []).collect(&:to_i) - [0]
  editable_role_ids = user.managed_roles(project).map(&:id)
  untouched_role_ids = self.role_ids - editable_role_ids
  touched_role_ids = ids & editable_role_ids
  self.role_ids = untouched_role_ids + touched_role_ids
end

#set_issue_category_nilObject


162
163
164
165
166
167
168
# File 'app/models/member.rb', line 162

def set_issue_category_nil
  if user_id && project_id
    # remove category based auto assignments for this member
    IssueCategory.where(["project_id = ? AND assigned_to_id = ?", project_id, user_id]).
      update_all("assigned_to_id = NULL")
  end
end