##// END OF EJS Templates
Speeds up Project.allowed_to_condition for users who belong to hundreds of projects....
Jean-Philippe Lang -
r15742:98f8a17851d5
parent child
Show More
@@ -204,9 +204,9 class Project < ActiveRecord::Base
204 statement_by_role[role] = s
204 statement_by_role[role] = s
205 end
205 end
206 end
206 end
207 user.projects_by_role.each do |role, projects|
207 user.project_ids_by_role.each do |role, project_ids|
208 if role.allowed_to?(permission) && projects.any?
208 if role.allowed_to?(permission) && project_ids.any?
209 statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.collect(&:id).join(',')})"
209 statement_by_role[role] = "#{Project.table_name}.id IN (#{project_ids.join(',')})"
210 end
210 end
211 end
211 end
212 if statement_by_role.empty?
212 if statement_by_role.empty?
@@ -163,6 +163,7 class User < Principal
163 def reload(*args)
163 def reload(*args)
164 @name = nil
164 @name = nil
165 @projects_by_role = nil
165 @projects_by_role = nil
166 @project_ids_by_role = nil
166 @membership_by_project_id = nil
167 @membership_by_project_id = nil
167 @notified_projects_ids = nil
168 @notified_projects_ids = nil
168 @notified_projects_ids_changed = false
169 @notified_projects_ids_changed = false
@@ -564,33 +565,51 class User < Principal
564 end
565 end
565
566
566 # Returns a hash of user's projects grouped by roles
567 # Returns a hash of user's projects grouped by roles
568 # TODO: No longer used, should be deprecated
567 def projects_by_role
569 def projects_by_role
568 return @projects_by_role if @projects_by_role
570 return @projects_by_role if @projects_by_role
569
571
570 hash = Hash.new([])
572 result = Hash.new([])
573 project_ids_by_role.each do |role, ids|
574 result[role] = Project.where(:id => ids).to_a
575 end
576 @projects_by_role = result
577 end
578
579 # Returns a hash of project ids grouped by roles.
580 # Includes the projects that the user is a member of and the projects
581 # that grant custom permissions to the builtin groups.
582 def project_ids_by_role
583 return @project_ids_by_role if @project_ids_by_role
571
584
572 group_class = anonymous? ? GroupAnonymous : GroupNonMember
585 group_class = anonymous? ? GroupAnonymous : GroupNonMember
573 members = Member.joins(:project, :principal).
586 group_id = group_class.pluck(:id).first
587
588 members = Member.joins(:project, :member_roles).
574 where("#{Project.table_name}.status <> 9").
589 where("#{Project.table_name}.status <> 9").
575 where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Principal.table_name}.type = ?)", self.id, true, group_class.name).
590 where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Member.table_name}.user_id = ?)", self.id, true, group_id).
576 preload(:project, :roles).
591 pluck(:user_id, :role_id, :project_id)
577 to_a
592
578
593 hash = {}
579 members.reject! {|member| member.user_id != id && project_ids.include?(member.project_id)}
594 members.each do |user_id, role_id, project_id|
580 members.each do |member|
595 # Ignore the roles of the builtin group if the user is a member of the project
581 if member.project
596 next if user_id != id && project_ids.include?(project_id)
582 member.roles.each do |role|
583 hash[role] = [] unless hash.key?(role)
584 hash[role] << member.project
585 end
586 end
587 end
588
597
589 hash.each do |role, projects|
598 hash[role_id] ||= []
590 projects.uniq!
599 hash[role_id] << project_id
591 end
600 end
592
601
593 @projects_by_role = hash
602 result = Hash.new([])
603 if hash.present?
604 roles = Role.where(:id => hash.keys).to_a
605 hash.each do |role_id, proj_ids|
606 role = roles.detect {|r| r.id == role_id}
607 if role
608 result[role] = proj_ids.uniq
609 end
610 end
611 end
612 @project_ids_by_role = result
594 end
613 end
595
614
596 # Returns the ids of visible projects
615 # Returns the ids of visible projects
General Comments 0
You need to be logged in to leave comments. Login now