Defect #13097
closedProject copy fails when wiki module is disabled
0%
Description
Information
Redmine 2.1.2
Ruby version              1.9.3 (x86_64-linux)
RubyGems version          1.8.24
Rack version              1.4
Rails version             3.2.8
Active Record version     3.2.8
Action Pack version       3.2.8
Active Resource version   3.2.8
Action Mailer version     3.2.8
Active Support version    3.2.8
Environment               production
Database adapter          mysql2
Database: mysql Ver 14.16 Distrib 5.2.12-MariaDB, for suse-linux-gnu (x86_64) using readline 5.1
Problem
When you copy a project that it doesn't have the wiki module activated, the copy crash. When you copy a project that have the wiki module activated there's no problem.
Code
In app/models/project.rb
def copy_wiki(project)
    # Check that the source project has a wiki first
    unless project.wiki.nil?
      self.wiki ||= Wiki.new
      wiki.attributes = project.wiki.attributes.dup.except("id", "project_id")
      wiki_pages_map = {}
      project.wiki.pages.each do |page|
        # Skip pages without content
        next if page.content.nil?
        new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on"))
        new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id"))
        new_wiki_page.content = new_wiki_content
        wiki.pages << new_wiki_page
        wiki_pages_map[page.id] = new_wiki_page
      end
      wiki.save
      # Reproduce page hierarchy
      project.wiki.pages.each do |page|
        if page.parent_id && wiki_pages_map[page.id]
          wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id]
          wiki_pages_map[page.id].save
        end
      end
    end
  end
	if you change the code it works correctly
def copy_wiki(project)
    # Check that the source project has a wiki first
    unless project.wiki.nil?
      wiki = Wiki.new
      wiki.attributes = project.wiki.attributes.dup.except("id", "project_id")
      wiki_pages_map = {}
      project.wiki.pages.each do |page|
        # Skip pages without content
        next if page.content.nil?
        new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on"))
        new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id"))
        new_wiki_page.content = new_wiki_content
        wiki.pages << new_wiki_page
        wiki_pages_map[page.id] = new_wiki_page
      end
      self.wiki = wiki
      wiki.save
      # Reproduce page hierarchy
      project.wiki.pages.each do |page|
        if page.parent_id && wiki_pages_map[page.id]
          wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id]
          wiki_pages_map[page.id].save
        end
      end
    end
  end
	Error log
Started POST "/projects/prova/copy" for 127.0.0.1 at 2013-02-07 11:54:14 +0100
Processing by ProjectsController#copy as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"R/TuuUitlFGsay8MNeshen6pJWpRaquVDl+fyFTVMN8=", "project"=>{"name"=>"testttt", "parent_id"=>"", "description"=>"dasdas", "identifier"=>"testttt", "homepage"=>"", "is_public"=>"0", "custom_field_values"=>{"1"=>"prova"}, "enabled_module_names"=>["issue_tracking", "time_tracking", "news", "documents", "files", "repository", "boards", "calendar", "gantt", "alfresco", "wiki_extensions", ""], "tracker_ids"=>["1", "2", "3", ""]}, "only"=>["members", "versions", "issue_categories", "issues", "queries", "boards", "wiki", ""], "commit"=>"Copia", "id"=>"prova"}
  [1m[36m (0.4ms)[0m  [1mSELECT MAX AS max_id FROM `settings` [0m
  [1m[35mUser Load (0.6ms)[0m  SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('User', 'AnonymousUser') AND `users`.`id` = 3 AND (users.status = 1) LIMIT 1
  Current user: gtanya (id=3)
  [1m[36m (0.1ms)[0m  [1mBEGIN[0m
  [1m[35m (0.2ms)[0m  SELECT * FROM concurrency_redmine FOR UPDATE
  [1m[36mIssueCustomField Load (0.3ms)[0m  [1mSELECT `custom_fields`.* FROM `custom_fields` WHERE `custom_fields`.`type` IN ('IssueCustomField') ORDER BY custom_fields.position[0m
  [1m[35mTracker Load (0.3ms)[0m  SELECT `trackers`.* FROM `trackers` ORDER BY trackers.position ASC
  [1m[36mProject Load (0.8ms)[0m  [1mSELECT `projects`.* FROM `projects` WHERE (parent_id IS NULL AND status = 1) ORDER BY name[0m
  [1m[35mProject Load (0.3ms)[0m  SELECT `projects`.* FROM `projects` WHERE `projects`.`identifier` = 'prova' LIMIT 1
  [1m[36mSetting Load (0.3ms)[0m  [1mSELECT `settings`.* FROM `settings` WHERE `settings`.`name` = 'default_projects_public' LIMIT 1[0m
  [1m[35mCACHE (0.0ms)[0m  SELECT `trackers`.* FROM `trackers` ORDER BY trackers.position ASC
  [1m[36mTracker Load (0.3ms)[0m  [1mSELECT `trackers`.* FROM `trackers` WHERE `trackers`.`id` IN (1, 2, 3)[0m
  [1m[35m (0.1ms)[0m  DELETE FROM `projects_trackers` WHERE `projects_trackers`.`project_id` IS NULL AND `projects_trackers`.`tracker_id` IN (4)
  [1m[36mCustomField Load (0.2ms)[0m  [1mSELECT `custom_fields`.* FROM `custom_fields` WHERE (type = 'ProjectCustomField') ORDER BY position[0m
  [1m[35mEnabledModule Exists (0.4ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'issue_tracking' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mEnabledModule Exists (0.3ms)[0m  [1mSELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'time_tracking' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'news' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mEnabledModule Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'documents' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'files' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mEnabledModule Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'repository' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'boards' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mEnabledModule Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'calendar' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'gantt' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mEnabledModule Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'alfresco' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'wiki_extensions' AND `enabled_modules`.`project_id` IS NULL) LIMIT 1
  [1m[36mProject Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM `projects` WHERE `projects`.`identifier` = BINARY 'testttt' LIMIT 1[0m
  [1m[35mProject Load (0.4ms)[0m  SELECT `projects`.* FROM `projects` ORDER BY `rgt` desc LIMIT 1 FOR UPDATE
  [1m[36mSQL (0.3ms)[0m  [1mINSERT INTO `projects` (`created_on`, `description`, `homepage`, `identifier`, `is_public`, `lft`, `name`, `parent_id`, `rgt`, `status`, `updated_on`) VALUES ('2013-02-07 11:54:14', 'dasdas', '', 'testttt', 0, 141, 'testttt', NULL, 142, 1, '2013-02-07 11:54:14')[0m
  [1m[35mEnabledModule Exists (0.5ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'issue_tracking' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.8ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('issue_tracking', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'time_tracking' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('time_tracking', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'news' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('news', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'documents' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('documents', 87)[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'files' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.1ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('files', 87)[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'repository' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.3ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('repository', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'boards' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('boards', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'calendar' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('calendar', 87)[0m
  [1m[35mEnabledModule Exists (0.3ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'gantt' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.1ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('gantt', 87)[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'alfresco' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('alfresco', 87)[0m
  [1m[35mEnabledModule Exists (0.2ms)[0m  SELECT 1 AS one FROM `enabled_modules` WHERE (`enabled_modules`.`name` = BINARY 'wiki_extensions' AND `enabled_modules`.`project_id` = 87) LIMIT 1
  [1m[36mSQL (0.1ms)[0m  [1mINSERT INTO `enabled_modules` (`name`, `project_id`) VALUES ('wiki_extensions', 87)[0m
  [1m[35m (0.1ms)[0m  INSERT INTO `projects_trackers` (`project_id`, `tracker_id`) VALUES (87, 1)
  [1m[36m (0.1ms)[0m  [1mINSERT INTO `projects_trackers` (`project_id`, `tracker_id`) VALUES (87, 2)[0m
  [1m[35m (0.1ms)[0m  INSERT INTO `projects_trackers` (`project_id`, `tracker_id`) VALUES (87, 3)
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `custom_values` (`custom_field_id`, `customized_id`, `customized_type`, `value`) VALUES (1, 87, 'Project', '')[0m
  [1m[35m (0.3ms)[0m  UPDATE `custom_values` SET `value` = 'prova' WHERE `custom_values`.`id` = 87
  [1m[36mProject Load (0.7ms)[0m  [1mSELECT `projects`.* FROM `projects` WHERE `projects`.`parent_id` IS NULL ORDER BY `lft`[0m
  [1m[35mProject Load (0.3ms)[0m  SELECT `lft`, `rgt`, `parent_id` FROM `projects` WHERE `projects`.`id` = 25 LIMIT 1 FOR UPDATE
  [1m[36mProject Load (0.2ms)[0m  [1mSELECT `lft`, `rgt`, `parent_id` FROM `projects` WHERE `projects`.`id` = 87 LIMIT 1 FOR UPDATE[0m
  [1m[35mSQL (1.0ms)[0m  UPDATE `projects` SET `lft` = CASE WHEN `lft` BETWEEN 123 AND 140 THEN `lft` + 142 - 140 WHEN `lft` BETWEEN 141 AND 142 THEN `lft` + 123 - 141 ELSE `lft` END, `rgt` = CASE WHEN `rgt` BETWEEN 123 AND 140 THEN `rgt` + 142 - 140 WHEN `rgt` BETWEEN 141 AND 142 THEN `rgt` + 123 - 141 ELSE `rgt` END, `parent_id` = CASE WHEN id = 87 THEN NULL ELSE `parent_id` END ORDER BY `projects`.`lft`
  [1m[36mProject Load (0.3ms)[0m  [1mSELECT `lft`, `rgt`, `parent_id` FROM `projects` WHERE `projects`.`id` = 25 LIMIT 1 FOR UPDATE[0m
  [1m[35mProject Load (0.3ms)[0m  SELECT `lft`, `rgt`, `parent_id` FROM `projects` WHERE `projects`.`id` = 87 LIMIT 1 FOR UPDATE
  [1m[36mProject Load (0.3ms)[0m  [1mSELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 87 LIMIT 1[0m
  [1m[35mWiki Load (0.4ms)[0m  SELECT `wikis`.* FROM `wikis` WHERE `wikis`.`project_id` = 1 LIMIT 1
  [1m[36mWiki Load (0.3ms)[0m  [1mSELECT `wikis`.* FROM `wikis` WHERE `wikis`.`project_id` = 87 LIMIT 1[0m
  [1m[35m (0.3ms)[0m  UPDATE concurrency_redmine SET id=id+1
  [1m[36m (14.6ms)[0m  [1mROLLBACK[0m
Completed 500 Internal Server Error in 121ms
ActiveRecord::RecordNotSaved (Failed to save the new associated wiki.):
  app/models/project.rb:724:in `copy_wiki'
  app/models/project.rb:675:in `block (2 levels) in copy'
  app/models/project.rb:674:in `each'
  app/models/project.rb:674:in `block in copy'
  app/models/project.rb:671:in `copy'
  app/controllers/projects_controller.rb:128:in `block in copy'
  app/models/mailer.rb:364:in `with_deliveries'
  app/controllers/projects_controller.rb:125:in `copy'