##// END OF EJS Templates
replaced deprecated ":dependent => true" statements...
Jean-Philippe Lang -
r120:b4d4b80dcd53
parent child
Show More
@@ -1,6 +1,23
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
1 class Comment < ActiveRecord::Base
18 class Comment < ActiveRecord::Base
2 belongs_to :commented, :polymorphic => true, :counter_cache => true
19 belongs_to :commented, :polymorphic => true, :counter_cache => true
3 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
4
21
5 validates_presence_of :commented, :author, :comment
22 validates_presence_of :commented, :author, :comment
6 end
23 end
@@ -1,43 +1,43
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class CustomField < ActiveRecord::Base
18 class CustomField < ActiveRecord::Base
19 has_many :custom_values, :dependent => true
19 has_many :custom_values, :dependent => :delete_all
20
20
21 FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
21 FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
22 "text" => { :name => :label_text, :order => 2 },
22 "text" => { :name => :label_text, :order => 2 },
23 "int" => { :name => :label_integer, :order => 3 },
23 "int" => { :name => :label_integer, :order => 3 },
24 "list" => { :name => :label_list, :order => 4 },
24 "list" => { :name => :label_list, :order => 4 },
25 "date" => { :name => :label_date, :order => 5 },
25 "date" => { :name => :label_date, :order => 5 },
26 "bool" => { :name => :label_boolean, :order => 6 }
26 "bool" => { :name => :label_boolean, :order => 6 }
27 }.freeze
27 }.freeze
28
28
29 validates_presence_of :name, :field_format
29 validates_presence_of :name, :field_format
30 validates_uniqueness_of :name
30 validates_uniqueness_of :name
31 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
31 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
32 validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
32 validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
33 validates_presence_of :possible_values, :if => Proc.new { |field| field.field_format == "list" }
33 validates_presence_of :possible_values, :if => Proc.new { |field| field.field_format == "list" }
34
34
35 # to move in project_custom_field
35 # to move in project_custom_field
36 def self.for_all
36 def self.for_all
37 find(:all, :conditions => ["is_for_all=?", true])
37 find(:all, :conditions => ["is_for_all=?", true])
38 end
38 end
39
39
40 def type_name
40 def type_name
41 nil
41 nil
42 end
42 end
43 end
43 end
@@ -1,24 +1,24
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Document < ActiveRecord::Base
18 class Document < ActiveRecord::Base
19 belongs_to :project
19 belongs_to :project
20 belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
20 belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
21 has_many :attachments, :as => :container, :dependent => true
21 has_many :attachments, :as => :container, :dependent => :destroy
22
22
23 validates_presence_of :project, :title, :category
23 validates_presence_of :project, :title, :category
24 end
24 end
@@ -1,103 +1,102
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Issue < ActiveRecord::Base
18 class Issue < ActiveRecord::Base
19
19
20 belongs_to :project
20 belongs_to :project
21 belongs_to :tracker
21 belongs_to :tracker
22 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
22 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
24 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
24 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
25 belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
25 belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
26 belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
26 belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
27 belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
27 belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
28
28
29 #has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
29 has_many :journals, :as => :journalized, :dependent => :destroy
30 has_many :journals, :as => :journalized, :dependent => true
30 has_many :attachments, :as => :container, :dependent => :destroy
31 has_many :attachments, :as => :container, :dependent => true
32
31
33 has_many :custom_values, :dependent => true, :as => :customized
32 has_many :custom_values, :dependent => :delete_all, :as => :customized
34 has_many :custom_fields, :through => :custom_values
33 has_many :custom_fields, :through => :custom_values
35
34
36 validates_presence_of :subject, :description, :priority, :tracker, :author, :status
35 validates_presence_of :subject, :description, :priority, :tracker, :author, :status
37 validates_inclusion_of :done_ratio, :in => 0..100
36 validates_inclusion_of :done_ratio, :in => 0..100
38 validates_associated :custom_values, :on => :update
37 validates_associated :custom_values, :on => :update
39
38
40 # set default status for new issues
39 # set default status for new issues
41 def before_validation
40 def before_validation
42 self.status = IssueStatus.default if new_record?
41 self.status = IssueStatus.default if new_record?
43 end
42 end
44
43
45 def validate
44 def validate
46 if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
45 if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
47 errors.add :due_date, :activerecord_error_not_a_date
46 errors.add :due_date, :activerecord_error_not_a_date
48 end
47 end
49
48
50 if self.due_date and self.start_date and self.due_date < self.start_date
49 if self.due_date and self.start_date and self.due_date < self.start_date
51 errors.add :due_date, :activerecord_error_greater_than_start_date
50 errors.add :due_date, :activerecord_error_greater_than_start_date
52 end
51 end
53 end
52 end
54
53
55 #def before_create
54 #def before_create
56 # build_history
55 # build_history
57 #end
56 #end
58
57
59 def before_save
58 def before_save
60 if @current_journal
59 if @current_journal
61 # attributes changes
60 # attributes changes
62 (Issue.column_names - %w(id description)).each {|c|
61 (Issue.column_names - %w(id description)).each {|c|
63 @current_journal.details << JournalDetail.new(:property => 'attr',
62 @current_journal.details << JournalDetail.new(:property => 'attr',
64 :prop_key => c,
63 :prop_key => c,
65 :old_value => @issue_before_change.send(c),
64 :old_value => @issue_before_change.send(c),
66 :value => send(c)) unless send(c)==@issue_before_change.send(c)
65 :value => send(c)) unless send(c)==@issue_before_change.send(c)
67 }
66 }
68 # custom fields changes
67 # custom fields changes
69 custom_values.each {|c|
68 custom_values.each {|c|
70 @current_journal.details << JournalDetail.new(:property => 'cf',
69 @current_journal.details << JournalDetail.new(:property => 'cf',
71 :prop_key => c.custom_field_id,
70 :prop_key => c.custom_field_id,
72 :old_value => @custom_values_before_change[c.custom_field_id],
71 :old_value => @custom_values_before_change[c.custom_field_id],
73 :value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
72 :value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
74 }
73 }
75 @current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
74 @current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
76 end
75 end
77 end
76 end
78
77
79 def long_id
78 def long_id
80 "%05d" % self.id
79 "%05d" % self.id
81 end
80 end
82
81
83 def custom_value_for(custom_field)
82 def custom_value_for(custom_field)
84 self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
83 self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
85 return nil
84 return nil
86 end
85 end
87
86
88 def init_journal(user, notes = "")
87 def init_journal(user, notes = "")
89 @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
88 @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
90 @issue_before_change = self.clone
89 @issue_before_change = self.clone
91 @custom_values_before_change = {}
90 @custom_values_before_change = {}
92 self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
91 self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
93 @current_journal
92 @current_journal
94 end
93 end
95
94
96 private
95 private
97 # Creates an history for the issue
96 # Creates an history for the issue
98 #def build_history
97 #def build_history
99 # @history = self.histories.build
98 # @history = self.histories.build
100 # @history.status = self.status
99 # @history.status = self.status
101 # @history.author = self.author
100 # @history.author = self.author
102 #end
101 #end
103 end
102 end
@@ -1,22 +1,22
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Journal < ActiveRecord::Base
18 class Journal < ActiveRecord::Base
19 belongs_to :journalized, :polymorphic => true
19 belongs_to :journalized, :polymorphic => true
20 belongs_to :user
20 belongs_to :user
21 has_many :details, :class_name => "JournalDetail", :dependent => true
21 has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
22 end
22 end
@@ -1,29 +1,29
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class News < ActiveRecord::Base
18 class News < ActiveRecord::Base
19 belongs_to :project
19 belongs_to :project
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
21 has_many :comments, :as => :commented, :dependent => true, :order => "created_on"
21 has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
22
22
23 validates_presence_of :title, :description
23 validates_presence_of :title, :description
24
24
25 # returns last created news
25 # returns last created news
26 def self.latest
26 def self.latest
27 find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
27 find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
28 end
28 end
29 end
29 end
@@ -1,61 +1,61
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Project < ActiveRecord::Base
18 class Project < ActiveRecord::Base
19 has_many :versions, :dependent => true, :order => "versions.effective_date DESC, versions.name DESC"
19 has_many :versions, :dependent => :destroy, :order => "versions.effective_date DESC, versions.name DESC"
20 has_many :members, :dependent => true, :include => :user, :conditions => "users.status=#{User::STATUS_ACTIVE}"
20 has_many :members, :dependent => :delete_all, :include => :user, :conditions => "users.status=#{User::STATUS_ACTIVE}"
21 has_many :users, :through => :members
21 has_many :users, :through => :members
22 has_many :custom_values, :dependent => true, :as => :customized
22 has_many :custom_values, :dependent => :delete_all, :as => :customized
23 has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => [:status, :tracker]
23 has_many :issues, :dependent => :destroy, :order => "issues.created_on DESC", :include => [:status, :tracker]
24 has_many :queries, :dependent => true
24 has_many :queries, :dependent => :delete_all
25 has_many :documents, :dependent => true
25 has_many :documents, :dependent => :destroy
26 has_many :news, :dependent => true, :include => :author
26 has_many :news, :dependent => :delete_all, :include => :author
27 has_many :issue_categories, :dependent => true, :order => "issue_categories.name"
27 has_many :issue_categories, :dependent => :delete_all, :order => "issue_categories.name"
28 has_one :repository, :dependent => true
28 has_one :repository, :dependent => :destroy
29 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
29 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
30 acts_as_tree :order => "name", :counter_cache => true
30 acts_as_tree :order => "name", :counter_cache => true
31
31
32 validates_presence_of :name, :description
32 validates_presence_of :name, :description
33 validates_uniqueness_of :name
33 validates_uniqueness_of :name
34 validates_associated :custom_values, :on => :update
34 validates_associated :custom_values, :on => :update
35 validates_associated :repository
35 validates_associated :repository
36 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
36 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
37
37
38 # returns 5 last created projects
38 # returns 5 last created projects
39 def self.latest
39 def self.latest
40 find(:all, :limit => 5, :order => "created_on DESC")
40 find(:all, :limit => 5, :order => "created_on DESC")
41 end
41 end
42
42
43 # Returns an array of all custom fields enabled for project issues
43 # Returns an array of all custom fields enabled for project issues
44 # (explictly associated custom fields and custom fields enabled for all projects)
44 # (explictly associated custom fields and custom fields enabled for all projects)
45 def custom_fields_for_issues(tracker)
45 def custom_fields_for_issues(tracker)
46 tracker.custom_fields.find(:all, :include => :projects,
46 tracker.custom_fields.find(:all, :include => :projects,
47 :conditions => ["is_for_all=? or project_id=?", true, self.id])
47 :conditions => ["is_for_all=? or project_id=?", true, self.id])
48 #(CustomField.for_all + custom_fields).uniq
48 #(CustomField.for_all + custom_fields).uniq
49 end
49 end
50
50
51 def all_custom_fields
51 def all_custom_fields
52 @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
52 @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
53 :conditions => ["is_for_all=? or project_id=?", true, self.id])
53 :conditions => ["is_for_all=? or project_id=?", true, self.id])
54 end
54 end
55
55
56 protected
56 protected
57 def validate
57 def validate
58 errors.add(parent_id, " must be a root project") if parent and parent.parent
58 errors.add(parent_id, " must be a root project") if parent and parent.parent
59 errors.add_to_base("A project with subprojects can't be a subproject") if parent and projects_count > 0
59 errors.add_to_base("A project with subprojects can't be a subproject") if parent and projects_count > 0
60 end
60 end
61 end
61 end
@@ -1,32 +1,32
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Role < ActiveRecord::Base
18 class Role < ActiveRecord::Base
19 before_destroy :check_integrity
19 before_destroy :check_integrity
20 has_and_belongs_to_many :permissions
20 has_and_belongs_to_many :permissions
21 has_many :workflows, :dependent => true
21 has_many :workflows, :dependent => :delete_all
22 has_many :members
22 has_many :members
23
23
24 validates_presence_of :name
24 validates_presence_of :name
25 validates_uniqueness_of :name
25 validates_uniqueness_of :name
26 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
26 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
27
27
28 private
28 private
29 def check_integrity
29 def check_integrity
30 raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
30 raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
31 end
31 end
32 end
32 end
@@ -1,32 +1,32
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Tracker < ActiveRecord::Base
18 class Tracker < ActiveRecord::Base
19 before_destroy :check_integrity
19 before_destroy :check_integrity
20 has_many :issues
20 has_many :issues
21 has_many :workflows, :dependent => true
21 has_many :workflows, :dependent => :delete_all
22 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
22 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
23
23
24 validates_presence_of :name
24 validates_presence_of :name
25 validates_uniqueness_of :name
25 validates_uniqueness_of :name
26 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
26 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
27
27
28 private
28 private
29 def check_integrity
29 def check_integrity
30 raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
30 raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
31 end
31 end
32 end
32 end
@@ -1,130 +1,130
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require "digest/sha1"
18 require "digest/sha1"
19
19
20 class User < ActiveRecord::Base
20 class User < ActiveRecord::Base
21 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
21 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => :delete_all
22 has_many :projects, :through => :memberships
22 has_many :projects, :through => :memberships
23 has_many :custom_values, :dependent => true, :as => :customized
23 has_many :custom_values, :dependent => :delete_all, :as => :customized
24 has_one :preference, :dependent => true, :class_name => 'UserPreference'
24 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
25 belongs_to :auth_source
25 belongs_to :auth_source
26
26
27 attr_accessor :password, :password_confirmation
27 attr_accessor :password, :password_confirmation
28 attr_accessor :last_before_login_on
28 attr_accessor :last_before_login_on
29 # Prevents unauthorized assignments
29 # Prevents unauthorized assignments
30 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
30 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
31
31
32 validates_presence_of :login, :firstname, :lastname, :mail
32 validates_presence_of :login, :firstname, :lastname, :mail
33 validates_uniqueness_of :login, :mail
33 validates_uniqueness_of :login, :mail
34 # Login must contain lettres, numbers, underscores only
34 # Login must contain lettres, numbers, underscores only
35 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
35 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
36 validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
36 validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
37 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
37 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
38 # Password length between 4 and 12
38 # Password length between 4 and 12
39 validates_length_of :password, :in => 4..12, :allow_nil => true
39 validates_length_of :password, :in => 4..12, :allow_nil => true
40 validates_confirmation_of :password, :allow_nil => true
40 validates_confirmation_of :password, :allow_nil => true
41 validates_associated :custom_values, :on => :update
41 validates_associated :custom_values, :on => :update
42
42
43 # Account statuses
43 # Account statuses
44 STATUS_ACTIVE = 1
44 STATUS_ACTIVE = 1
45 STATUS_REGISTERED = 2
45 STATUS_REGISTERED = 2
46 STATUS_LOCKED = 3
46 STATUS_LOCKED = 3
47
47
48 def before_save
48 def before_save
49 # update hashed_password if password was set
49 # update hashed_password if password was set
50 self.hashed_password = User.hash_password(self.password) if self.password
50 self.hashed_password = User.hash_password(self.password) if self.password
51 end
51 end
52
52
53 # Returns the user that matches provided login and password, or nil
53 # Returns the user that matches provided login and password, or nil
54 def self.try_to_login(login, password)
54 def self.try_to_login(login, password)
55 user = find(:first, :conditions => ["login=?", login])
55 user = find(:first, :conditions => ["login=?", login])
56 if user
56 if user
57 # user is already in local database
57 # user is already in local database
58 return nil if !user.active?
58 return nil if !user.active?
59 if user.auth_source
59 if user.auth_source
60 # user has an external authentication method
60 # user has an external authentication method
61 return nil unless user.auth_source.authenticate(login, password)
61 return nil unless user.auth_source.authenticate(login, password)
62 else
62 else
63 # authentication with local password
63 # authentication with local password
64 return nil unless User.hash_password(password) == user.hashed_password
64 return nil unless User.hash_password(password) == user.hashed_password
65 end
65 end
66 else
66 else
67 # user is not yet registered, try to authenticate with available sources
67 # user is not yet registered, try to authenticate with available sources
68 attrs = AuthSource.authenticate(login, password)
68 attrs = AuthSource.authenticate(login, password)
69 if attrs
69 if attrs
70 onthefly = new(*attrs)
70 onthefly = new(*attrs)
71 onthefly.login = login
71 onthefly.login = login
72 onthefly.language = $RDM_DEFAULT_LANG
72 onthefly.language = $RDM_DEFAULT_LANG
73 if onthefly.save
73 if onthefly.save
74 user = find(:first, :conditions => ["login=?", login])
74 user = find(:first, :conditions => ["login=?", login])
75 logger.info("User '#{user.login}' created on the fly.") if logger
75 logger.info("User '#{user.login}' created on the fly.") if logger
76 end
76 end
77 end
77 end
78 end
78 end
79 user.update_attribute(:last_login_on, Time.now) if user
79 user.update_attribute(:last_login_on, Time.now) if user
80 user
80 user
81
81
82 rescue => text
82 rescue => text
83 raise text
83 raise text
84 end
84 end
85
85
86 # Return user's full name for display
86 # Return user's full name for display
87 def display_name
87 def display_name
88 firstname + " " + lastname
88 firstname + " " + lastname
89 end
89 end
90
90
91 def name
91 def name
92 display_name
92 display_name
93 end
93 end
94
94
95 def active?
95 def active?
96 self.status == STATUS_ACTIVE
96 self.status == STATUS_ACTIVE
97 end
97 end
98
98
99 def registered?
99 def registered?
100 self.status == STATUS_REGISTERED
100 self.status == STATUS_REGISTERED
101 end
101 end
102
102
103 def locked?
103 def locked?
104 self.status == STATUS_LOCKED
104 self.status == STATUS_LOCKED
105 end
105 end
106
106
107 def check_password?(clear_password)
107 def check_password?(clear_password)
108 User.hash_password(clear_password) == self.hashed_password
108 User.hash_password(clear_password) == self.hashed_password
109 end
109 end
110
110
111 def role_for_project(project_id)
111 def role_for_project(project_id)
112 @role_for_projects ||=
112 @role_for_projects ||=
113 begin
113 begin
114 roles = {}
114 roles = {}
115 self.memberships.each { |m| roles.store m.project_id, m.role_id }
115 self.memberships.each { |m| roles.store m.project_id, m.role_id }
116 roles
116 roles
117 end
117 end
118 @role_for_projects[project_id]
118 @role_for_projects[project_id]
119 end
119 end
120
120
121 def pref
121 def pref
122 self.preference ||= UserPreference.new(:user => self)
122 self.preference ||= UserPreference.new(:user => self)
123 end
123 end
124
124
125 private
125 private
126 # Return password digest
126 # Return password digest
127 def self.hash_password(clear_password)
127 def self.hash_password(clear_password)
128 Digest::SHA1.hexdigest(clear_password || "")
128 Digest::SHA1.hexdigest(clear_password || "")
129 end
129 end
130 end
130 end
@@ -1,32 +1,32
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Version < ActiveRecord::Base
18 class Version < ActiveRecord::Base
19 before_destroy :check_integrity
19 before_destroy :check_integrity
20 belongs_to :project
20 belongs_to :project
21 has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
21 has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
22 has_many :attachments, :as => :container, :dependent => true
22 has_many :attachments, :as => :container, :dependent => :destroy
23
23
24 validates_presence_of :name
24 validates_presence_of :name
25 validates_uniqueness_of :name, :scope => [:project_id]
25 validates_uniqueness_of :name, :scope => [:project_id]
26 validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date
26 validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date
27
27
28 private
28 private
29 def check_integrity
29 def check_integrity
30 raise "Can't delete version" if self.fixed_issues.find(:first)
30 raise "Can't delete version" if self.fixed_issues.find(:first)
31 end
31 end
32 end
32 end
General Comments 0
You need to be logged in to leave comments. Login now