From b7a9e41bd269e2b5519928c35592aad96d3707c6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 14:52:17 +0300 Subject: [PATCH] Handle perfomance issue with team import. Model specs --- app/models/users_project.rb | 31 ++++++++++++++++++++--------- spec/models/users_project_spec.rb | 33 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 3c1fe213..967c78f2 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -22,19 +22,32 @@ class UsersProject < ActiveRecord::Base class << self def import_team(source_project, target_project) - UsersProject.transaction do - team = source_project.users_projects.all + UsersProject.without_repository_callback do + UsersProject.transaction do + team = source_project.users_projects.all - team.each do |tm| - # Skip if user already present in team - next if target_project.users.include?(tm.user) + team.each do |tm| + # Skip if user already present in team + next if target_project.users.include?(tm.user) - new_tm = tm.dup - new_tm.id = nil - new_tm.project_id = target_project.id - new_tm.save + new_tm = tm.dup + new_tm.id = nil + new_tm.project_id = target_project.id + new_tm.save + end end end + + target_project.update_repository + true + rescue + false + end + + def without_repository_callback + UsersProject.skip_callback(:destroy, :after, :update_repository) + yield + UsersProject.set_callback(:destroy, :after, :update_repository) end def bulk_delete(project, user_ids) diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb index 5b6516b3..2ad9a0bd 100644 --- a/spec/models/users_project_spec.rb +++ b/spec/models/users_project_spec.rb @@ -35,4 +35,37 @@ describe UsersProject do it { should respond_to(:user_name) } it { should respond_to(:user_email) } end + + describe :import_team do + before do + @abilities = Six.new + @abilities << Ability + + @project_1 = create :project + @project_2 = create :project + + @user_1 = create :user + @user_2 = create :user + + @project_1.add_access @user_1, :write + @project_2.add_access @user_2, :read + + @status = UsersProject.import_team(@project_1, @project_2) + end + + it { @status.should be_true } + + describe 'project 2 should get user 1 as developer. user_2 should not be changed' do + it { @project_2.users.should include(@user_1) } + it { @project_2.users.should include(@user_2) } + + it { @abilities.allowed?(@user_1, :write_project, @project_2).should be_true } + it { @abilities.allowed?(@user_2, :read_project, @project_2).should be_true } + end + + describe 'project 1 should not be changed' do + it { @project_1.users.should include(@user_1) } + it { @project_1.users.should_not include(@user_2) } + end + end end