Class: Member

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

Overview

Redmine - project management software Copyright (C) 2006-2020 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]

200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'app/models/member.rb', line 200

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


216
217
218
219
220
221
222
223
# File 'app/models/member.rb', line 216

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


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'app/models/member.rb', line 78

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)

104
105
106
# File 'app/models/member.rb', line 104

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

#base_reloadObject


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

alias :base_reload :reload

#base_role_ids=Object


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

alias :base_role_ids= :role_ids=

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

Returns true if the member is deletable by user

Returns:

  • (Boolean)

133
134
135
136
137
138
139
# File 'app/models/member.rb', line 133

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

#destroyObject

Destroys the member


142
143
144
145
# File 'app/models/member.rb', line 142

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)

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

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)

149
150
151
152
153
154
155
# File 'app/models/member.rb', line 149

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


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'app/models/member.rb', line 174

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


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

def name
  self.user.name
end

#reload(*args) ⇒ Object


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

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

#remove_from_project_default_assigned_toObject


165
166
167
168
169
170
# File 'app/models/member.rb', line 165

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


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

def role
end

#role=Object


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

def role=
end

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

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

Returns:

  • (Boolean)

124
125
126
127
128
129
130
# File 'app/models/member.rb', line 124

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


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

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 {|id| member_roles << MemberRole.new(:role_id => id, :member => self) }
  # 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
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


115
116
117
118
119
120
121
# File 'app/models/member.rb', line 115

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


95
96
97
98
99
100
101
# File 'app/models/member.rb', line 95

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


157
158
159
160
161
162
163
# File 'app/models/member.rb', line 157

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