Commit e0d0c1b225e6d693b7a43b09b74f97dd70444433

Authored by Dmitriy Zaporozhets
2 parents 80bfd6a5 a030e4b6

Merge pull request #1570 from NARKOZ/refactoring

models cleanup
app/models/ability.rb
... ... @@ -52,7 +52,6 @@ class Ability
52 52 :admin_wiki
53 53 ] if project.master_access_for?(user) || project.owner == user
54 54  
55   -
56 55 rules.flatten
57 56 end
58 57  
... ...
app/models/commit.rb
... ... @@ -4,24 +4,11 @@ class Commit
4 4 include StaticModel
5 5 extend ActiveModel::Naming
6 6  
7   - attr_accessor :commit
8   - attr_accessor :head
9   - attr_accessor :refs
10   -
11   - delegate :message,
12   - :authored_date,
13   - :committed_date,
14   - :parents,
15   - :sha,
16   - :date,
17   - :committer,
18   - :author,
19   - :message,
20   - :diffs,
21   - :tree,
22   - :id,
23   - :to_patch,
24   - to: :commit
  7 + attr_accessor :commit, :head, :refs
  8 +
  9 + delegate :message, :authored_date, :committed_date, :parents, :sha,
  10 + :date, :committer, :author, :message, :diffs, :tree, :id,
  11 + :to_patch, to: :commit
25 12  
26 13 class << self
27 14 def find_or_first(repo, commit_id = nil, root_ref)
... ... @@ -30,6 +17,7 @@ class Commit
30 17 else
31 18 repo.commits(root_ref).first
32 19 end
  20 +
33 21 Commit.new(commit) if commit
34 22 end
35 23  
... ...
app/models/event.rb
... ... @@ -16,6 +16,10 @@ class Event &lt; ActiveRecord::Base
16 16 Joined = 8 # User joined project
17 17 Left = 9 # User left project
18 18  
  19 + delegate :name, :email, to: :author, prefix: true, allow_nil: true
  20 + delegate :title, to: :issue, prefix: true, allow_nil: true
  21 + delegate :title, to: :merge_request, prefix: true, allow_nil: true
  22 +
19 23 belongs_to :project
20 24 belongs_to :target, polymorphic: true
21 25  
... ... @@ -134,25 +138,20 @@ class Event &lt; ActiveRecord::Base
134 138 "opened"
135 139 end
136 140 end
137   -
138   -
139   - delegate :name, :email, to: :author, prefix: true, allow_nil: true
140   - delegate :title, to: :issue, prefix: true, allow_nil: true
141   - delegate :title, to: :merge_request, prefix: true, allow_nil: true
142 141 end
  142 +
143 143 # == Schema Information
144 144 #
145 145 # Table name: events
146 146 #
147   -# id :integer(4) not null, primary key
  147 +# id :integer not null, primary key
148 148 # target_type :string(255)
149   -# target_id :integer(4)
  149 +# target_id :integer
150 150 # title :string(255)
151 151 # data :text
152   -# project_id :integer(4)
  152 +# project_id :integer
153 153 # created_at :datetime not null
154 154 # updated_at :datetime not null
155   -# action :integer(4)
156   -# author_id :integer(4)
  155 +# action :integer
  156 +# author_id :integer
157 157 #
158   -
... ...
app/models/issue.rb
... ... @@ -9,8 +9,7 @@ class Issue &lt; ActiveRecord::Base
9 9  
10 10 belongs_to :milestone
11 11  
12   - validates :description,
13   - length: { within: 0..2000 }
  12 + validates :description, length: { within: 0..2000 }
14 13  
15 14 def self.open_for(user)
16 15 opened.assigned(user)
... ... @@ -32,22 +31,21 @@ class Issue &lt; ActiveRecord::Base
32 31 closed_changed? && !closed
33 32 end
34 33 end
  34 +
35 35 # == Schema Information
36 36 #
37 37 # Table name: issues
38 38 #
39   -# id :integer(4) not null, primary key
  39 +# id :integer not null, primary key
40 40 # title :string(255)
41   -# assignee_id :integer(4)
42   -# author_id :integer(4)
43   -# project_id :integer(4)
  41 +# assignee_id :integer
  42 +# author_id :integer
  43 +# project_id :integer
44 44 # created_at :datetime not null
45 45 # updated_at :datetime not null
46   -# closed :boolean(1) default(FALSE), not null
47   -# position :integer(4) default(0)
48   -# critical :boolean(1) default(FALSE), not null
  46 +# closed :boolean default(FALSE), not null
  47 +# position :integer default(0)
49 48 # branch_name :string(255)
50 49 # description :text
51   -# milestone_id :integer(4)
  50 +# milestone_id :integer
52 51 #
53   -
... ...
app/models/key.rb
... ... @@ -6,14 +6,10 @@ class Key &lt; ActiveRecord::Base
6 6  
7 7 attr_accessible :key, :title
8 8  
9   - validates :title,
10   - presence: true,
11   - length: { within: 0..255 }
12   -
13   - validates :key,
14   - presence: true,
15   - format: { :with => /ssh-.{3} / },
16   - length: { within: 0..5000 }
  9 + validates :title, presence: true, length: { within: 0..255 }
  10 + validates :key, presence: true,
  11 + length: { within: 0..5000 },
  12 + format: { :with => /ssh-.{3} / }
17 13  
18 14 before_save :set_identifier
19 15 before_validation :strip_white_space
... ... @@ -34,7 +30,7 @@ class Key &lt; ActiveRecord::Base
34 30  
35 31 def set_identifier
36 32 if is_deploy_key
37   - self.identifier = "deploy_" + Digest::MD5.hexdigest(key)
  33 + self.identifier = "deploy_#{Digest::MD5.hexdigest(key)}"
38 34 else
39 35 self.identifier = "#{user.identifier}_#{Time.now.to_i}"
40 36 end
... ... @@ -57,17 +53,17 @@ class Key &lt; ActiveRecord::Base
57 53 Key.where(identifier: identifier).count == 0
58 54 end
59 55 end
  56 +
60 57 # == Schema Information
61 58 #
62 59 # Table name: keys
63 60 #
64   -# id :integer(4) not null, primary key
65   -# user_id :integer(4)
  61 +# id :integer not null, primary key
  62 +# user_id :integer
66 63 # created_at :datetime not null
67 64 # updated_at :datetime not null
68 65 # key :text
69 66 # title :string(255)
70 67 # identifier :string(255)
71   -# project_id :integer(4)
  68 +# project_id :integer
72 69 #
73   -
... ...
app/models/merge_request.rb
... ... @@ -18,8 +18,7 @@ class MergeRequest &lt; ActiveRecord::Base
18 18  
19 19 attr_accessor :should_remove_source_branch
20 20  
21   - validates_presence_of :source_branch
22   - validates_presence_of :target_branch
  21 + validates_presence_of :source_branch, :target_branch
23 22 validate :validate_branches
24 23  
25 24 def self.find_all_by_branch(branch_name)
... ... @@ -187,23 +186,23 @@ class MergeRequest &lt; ActiveRecord::Base
187 186 patch_path
188 187 end
189 188 end
  189 +
190 190 # == Schema Information
191 191 #
192 192 # Table name: merge_requests
193 193 #
194   -# id :integer(4) not null, primary key
  194 +# id :integer not null, primary key
195 195 # target_branch :string(255) not null
196 196 # source_branch :string(255) not null
197   -# project_id :integer(4) not null
198   -# author_id :integer(4)
199   -# assignee_id :integer(4)
  197 +# project_id :integer not null
  198 +# author_id :integer
  199 +# assignee_id :integer
200 200 # title :string(255)
201   -# closed :boolean(1) default(FALSE), not null
  201 +# closed :boolean default(FALSE), not null
202 202 # created_at :datetime not null
203 203 # updated_at :datetime not null
204 204 # st_commits :text(2147483647
205 205 # st_diffs :text(2147483647
206   -# merged :boolean(1) default(FALSE), not null
207   -# state :integer(4) default(1), not null
  206 +# merged :boolean default(FALSE), not null
  207 +# state :integer default(1), not null
208 208 #
209   -
... ...
app/models/milestone.rb
1   -# == Schema Information
2   -#
3   -# Table name: milestones
4   -#
5   -# id :integer(4) not null, primary key
6   -# title :string(255) not null
7   -# project_id :integer(4) not null
8   -# description :text
9   -# due_date :date
10   -# closed :boolean(1) default(FALSE), not null
11   -# created_at :datetime not null
12   -# updated_at :datetime not null
13   -#
14   -
15 1 class Milestone < ActiveRecord::Base
16 2 attr_accessible :title, :description, :due_date, :closed
17 3  
18 4 belongs_to :project
19 5 has_many :issues
20 6  
21   - validates_presence_of :project_id
22   - validates_presence_of :title
  7 + validates_presence_of :title, :project_id
23 8  
24 9 def self.active
25 10 where("due_date > ? OR due_date IS NULL", Date.today)
26 11 end
27 12  
28 13 def participants
29   - User.where(id: issues.map(&:assignee_id))
  14 + User.where(id: issues.pluck(:assignee_id))
30 15 end
31 16  
32 17 def percent_complete
... ... @@ -39,3 +24,17 @@ class Milestone &lt; ActiveRecord::Base
39 24 "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
40 25 end
41 26 end
  27 +
  28 +# == Schema Information
  29 +#
  30 +# Table name: milestones
  31 +#
  32 +# id :integer not null, primary key
  33 +# title :string(255) not null
  34 +# project_id :integer not null
  35 +# description :text
  36 +# due_date :date
  37 +# closed :boolean default(FALSE), not null
  38 +# created_at :datetime not null
  39 +# updated_at :datetime not null
  40 +#
... ...
app/models/note.rb
... ... @@ -2,39 +2,26 @@ require &#39;carrierwave/orm/activerecord&#39;
2 2 require 'file_size_validator'
3 3  
4 4 class Note < ActiveRecord::Base
  5 + mount_uploader :attachment, AttachmentUploader
5 6 attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
6 7 :attachment, :line_code
7 8  
8 9 belongs_to :project
9 10 belongs_to :noteable, polymorphic: true
10   - belongs_to :author,
11   - class_name: "User"
  11 + belongs_to :author, class_name: "User"
12 12  
13   - delegate :name,
14   - to: :project,
15   - prefix: true
16   -
17   - delegate :name,
18   - :email,
19   - to: :author,
20   - prefix: true
  13 + delegate :name, to: :project, prefix: true
  14 + delegate :name, :email, to: :author, prefix: true
21 15  
22 16 attr_accessor :notify
23 17 attr_accessor :notify_author
24 18  
25 19 validates_presence_of :project
26 20  
27   - validates :note,
28   - presence: true,
29   - length: { within: 0..5000 }
30   -
31   - validates :attachment,
32   - file_size: {
33   - maximum: 10.megabytes.to_i
34   - }
  21 + validates :note, presence: true, length: { within: 0..5000 }
  22 + validates :attachment, file_size: { maximum: 10.megabytes.to_i }
35 23  
36 24 scope :common, where(noteable_id: nil)
37   -
38 25 scope :today, where("created_at >= :date", date: Date.today)
39 26 scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
40 27 scope :since, lambda { |day| where("created_at >= :date", date: (day)) }
... ... @@ -42,14 +29,13 @@ class Note &lt; ActiveRecord::Base
42 29 scope :inc_author_project, includes(:project, :author)
43 30 scope :inc_author, includes(:author)
44 31  
45   - mount_uploader :attachment, AttachmentUploader
46   -
47 32 def self.create_status_change_note(noteable, author, status)
48   - create({ noteable: noteable,
49   - project: noteable.project,
50   - author: author,
51   - note: "_Status changed to #{status}_" },
52   - without_protection: true)
  33 + create({
  34 + noteable: noteable,
  35 + project: noteable.project,
  36 + author: author,
  37 + note: "_Status changed to #{status}_"
  38 + }, without_protection: true)
53 39 end
54 40  
55 41 def notify
... ... @@ -114,19 +100,19 @@ class Note &lt; ActiveRecord::Base
114 100 note.start_with?('-1') || note.start_with?(':-1:')
115 101 end
116 102 end
  103 +
117 104 # == Schema Information
118 105 #
119 106 # Table name: notes
120 107 #
121   -# id :integer(4) not null, primary key
  108 +# id :integer not null, primary key
122 109 # note :text
123 110 # noteable_id :string(255)
124 111 # noteable_type :string(255)
125   -# author_id :integer(4)
  112 +# author_id :integer
126 113 # created_at :datetime not null
127 114 # updated_at :datetime not null
128   -# project_id :integer(4)
  115 +# project_id :integer
129 116 # attachment :string(255)
130 117 # line_code :string(255)
131 118 #
132   -
... ...
app/models/project.rb
... ... @@ -8,10 +8,9 @@ class Project &lt; ActiveRecord::Base
8 8  
9 9 attr_accessible :name, :path, :description, :code, :default_branch, :issues_enabled,
10 10 :wall_enabled, :merge_requests_enabled, :wiki_enabled
  11 + attr_accessor :error_code
11 12  
12   - #
13 13 # Relations
14   - #
15 14 belongs_to :owner, class_name: "User"
16 15 has_many :users, through: :users_projects
17 16 has_many :events, dependent: :destroy
... ... @@ -26,11 +25,7 @@ class Project &lt; ActiveRecord::Base
26 25 has_many :wikis, dependent: :destroy
27 26 has_many :protected_branches, dependent: :destroy
28 27  
29   - attr_accessor :error_code
30   -
31   - #
32 28 # Scopes
33   - #
34 29 scope :public_only, where(private_flag: false)
35 30 scope :without_user, lambda { |user| where("id not in (:ids)", ids: user.projects.map(&:id) ) }
36 31  
... ... @@ -47,7 +42,6 @@ class Project &lt; ActiveRecord::Base
47 42  
48 43 Project.transaction do
49 44 project.owner = user
50   -
51 45 project.save!
52 46  
53 47 # Add user as project master
... ... @@ -76,36 +70,19 @@ class Project &lt; ActiveRecord::Base
76 70 id && valid?
77 71 end
78 72  
79   - #
80 73 # Validations
81   - #
82   - validates :name,
83   - uniqueness: true,
84   - presence: true,
85   - length: { within: 0..255 }
86   -
87   - validates :path,
88   - uniqueness: true,
89   - presence: true,
90   - format: { with: /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
91   - message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
92   - length: { within: 0..255 }
93   -
94   - validates :description,
95   - length: { within: 0..2000 }
96   -
97   - validates :code,
98   - presence: true,
99   - uniqueness: true,
100   - format: { with: /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
101   - message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
102   - length: { within: 1..255 }
103   -
104 74 validates :owner, presence: true
  75 + validates :description, length: { within: 0..2000 }
  76 + validates :name, uniqueness: true, presence: true, length: { within: 0..255 }
  77 + validates :path, uniqueness: true, presence: true, length: { within: 0..255 },
  78 + format: { with: /\A[a-zA-Z][a-zA-Z0-9_\-\.]*\z/,
  79 + message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
  80 + validates :code, presence: true, uniqueness: true, length: { within: 1..255 },
  81 + format: { with: /\A[a-zA-Z][a-zA-Z0-9_\-\.]*\z/,
  82 + message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
105 83 validates :issues_enabled, :wall_enabled, :merge_requests_enabled,
106 84 :wiki_enabled, inclusion: { in: [true, false] }
107   - validate :check_limit
108   - validate :repo_name
  85 + validate :check_limit, :repo_name
109 86  
110 87 def check_limit
111 88 unless owner.can_create_project?
... ... @@ -170,7 +147,7 @@ class Project &lt; ActiveRecord::Base
170 147 end
171 148  
172 149 def wiki_notes
173   - Note.where(noteable_id: wikis.map(&:id), noteable_type: 'Wiki', project_id: self.id)
  150 + Note.where(noteable_id: wikis.pluck(:id), noteable_type: 'Wiki', project_id: self.id)
174 151 end
175 152  
176 153 def project_id
... ... @@ -182,19 +159,18 @@ end
182 159 #
183 160 # Table name: projects
184 161 #
185   -# id :integer(4) not null, primary key
  162 +# id :integer not null, primary key
186 163 # name :string(255)
187 164 # path :string(255)
188 165 # description :text
189 166 # created_at :datetime not null
190 167 # updated_at :datetime not null
191   -# private_flag :boolean(1) default(TRUE), not null
  168 +# private_flag :boolean default(TRUE), not null
192 169 # code :string(255)
193   -# owner_id :integer(4)
  170 +# owner_id :integer
194 171 # default_branch :string(255)
195   -# issues_enabled :boolean(1) default(TRUE), not null
196   -# wall_enabled :boolean(1) default(TRUE), not null
197   -# merge_requests_enabled :boolean(1) default(TRUE), not null
198   -# wiki_enabled :boolean(1) default(TRUE), not null
  172 +# issues_enabled :boolean default(TRUE), not null
  173 +# wall_enabled :boolean default(TRUE), not null
  174 +# merge_requests_enabled :boolean default(TRUE), not null
  175 +# wiki_enabled :boolean default(TRUE), not null
199 176 #
200   -
... ...
app/models/project_hook.rb
1 1 class ProjectHook < WebHook
2 2 belongs_to :project
3 3 end
  4 +
  5 +# == Schema Information
  6 +#
  7 +# Table name: web_hooks
  8 +#
  9 +# id :integer not null, primary key
  10 +# url :string(255)
  11 +# project_id :integer
  12 +# created_at :datetime not null
  13 +# updated_at :datetime not null
  14 +# type :string(255) default("ProjectHook")
  15 +#
... ...
app/models/protected_branch.rb
... ... @@ -4,8 +4,7 @@ class ProtectedBranch &lt; ActiveRecord::Base
4 4 attr_accessible :name
5 5  
6 6 belongs_to :project
7   - validates_presence_of :project_id
8   - validates_presence_of :name
  7 + validates_presence_of :name, :project_id
9 8  
10 9 after_save :update_repository
11 10 after_destroy :update_repository
... ... @@ -18,14 +17,14 @@ class ProtectedBranch &lt; ActiveRecord::Base
18 17 project.commit(self.name)
19 18 end
20 19 end
  20 +
21 21 # == Schema Information
22 22 #
23 23 # Table name: protected_branches
24 24 #
25   -# id :integer(4) not null, primary key
26   -# project_id :integer(4) not null
  25 +# id :integer not null, primary key
  26 +# project_id :integer not null
27 27 # name :string(255) not null
28 28 # created_at :datetime not null
29 29 # updated_at :datetime not null
30 30 #
31   -
... ...
app/models/snippet.rb
... ... @@ -7,25 +7,12 @@ class Snippet &lt; ActiveRecord::Base
7 7 belongs_to :author, class_name: "User"
8 8 has_many :notes, as: :noteable, dependent: :destroy
9 9  
10   - delegate :name,
11   - :email,
12   - to: :author,
13   - prefix: true
  10 + delegate :name, :email, to: :author, prefix: true
14 11  
15   - validates_presence_of :project_id
16   - validates_presence_of :author_id
17   -
18   - validates :title,
19   - presence: true,
20   - length: { within: 0..255 }
21   -
22   - validates :file_name,
23   - presence: true,
24   - length: { within: 0..255 }
25   -
26   - validates :content,
27   - presence: true,
28   - length: { within: 0..10000 }
  12 + validates_presence_of :author_id, :project_id
  13 + validates :title, presence: true, length: { within: 0..255 }
  14 + validates :file_name, presence: true, length: { within: 0..255 }
  15 + validates :content, presence: true, length: { within: 0..10000 }
29 16  
30 17 scope :fresh, order("created_at DESC")
31 18 scope :non_expired, where(["expires_at IS NULL OR expires_at > ?", Time.current])
... ... @@ -59,18 +46,18 @@ class Snippet &lt; ActiveRecord::Base
59 46 expires_at && expires_at < Time.current
60 47 end
61 48 end
  49 +
62 50 # == Schema Information
63 51 #
64 52 # Table name: snippets
65 53 #
66   -# id :integer(4) not null, primary key
  54 +# id :integer not null, primary key
67 55 # title :string(255)
68 56 # content :text
69   -# author_id :integer(4) not null
70   -# project_id :integer(4) not null
  57 +# author_id :integer not null
  58 +# project_id :integer not null
71 59 # created_at :datetime not null
72 60 # updated_at :datetime not null
73 61 # file_name :string(255)
74 62 # expires_at :datetime
75 63 #
76   -
... ...
app/models/system_hook.rb
1 1 class SystemHook < WebHook
2   -
3 2 def async_execute(data)
4 3 Resque.enqueue(SystemHookWorker, id, data)
5 4 end
... ... @@ -9,5 +8,16 @@ class SystemHook &lt; WebHook
9 8 sh.async_execute data
10 9 end
11 10 end
12   -
13 11 end
  12 +
  13 +# == Schema Information
  14 +#
  15 +# Table name: web_hooks
  16 +#
  17 +# id :integer not null, primary key
  18 +# url :string(255)
  19 +# project_id :integer
  20 +# created_at :datetime not null
  21 +# updated_at :datetime not null
  22 +# type :string(255) default("ProjectHook")
  23 +#
... ...
app/models/tree.rb
... ... @@ -2,16 +2,8 @@ class Tree
2 2 include Linguist::BlobHelper
3 3 attr_accessor :path, :tree, :project, :ref
4 4  
5   - delegate :contents,
6   - :basename,
7   - :name,
8   - :data,
9   - :mime_type,
10   - :mode,
11   - :size,
12   - :text?,
13   - :colorize,
14   - to: :tree
  5 + delegate :contents, :basename, :name, :data, :mime_type,
  6 + :mode, :size, :text?, :colorize, to: :tree
15 7  
16 8 def initialize(raw_tree, project, ref = nil, path = nil)
17 9 @project, @ref, @path = project, ref, path
... ...
app/models/user.rb
1 1 class User < ActiveRecord::Base
2   -
3 2 include Account
4 3  
5 4 devise :database_authenticatable, :token_authenticatable, :lockable,
6 5 :recoverable, :rememberable, :trackable, :validatable, :omniauthable
7 6  
8   - attr_accessible :email, :password, :password_confirmation, :remember_me, :bio,
9   - :name, :skype, :linkedin, :twitter, :dark_scheme,
10   - :theme_id, :force_random_password, :extern_uid, :provider, :as => [:default, :admin]
  7 + attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name,
  8 + :skype, :linkedin, :twitter, :dark_scheme, :theme_id, :force_random_password,
  9 + :extern_uid, :provider, :as => [:default, :admin]
11 10 attr_accessible :projects_limit, :as => :admin
12 11  
13 12 attr_accessor :force_random_password
14 13  
15   - has_many :users_projects, dependent: :destroy
  14 + has_many :keys, dependent: :destroy
16 15 has_many :projects, through: :users_projects
  16 + has_many :users_projects, dependent: :destroy
  17 + has_many :issues, foreign_key: :author_id, dependent: :destroy
  18 + has_many :notes, foreign_key: :author_id, dependent: :destroy
  19 + has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
17 20 has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id
18   - has_many :keys, dependent: :destroy
19   -
20   - has_many :events,
21   - class_name: "Event",
22   - foreign_key: :author_id,
23   - dependent: :destroy
24   -
25   - has_many :recent_events,
26   - class_name: "Event",
27   - foreign_key: :author_id,
28   - order: "id DESC"
29   -
30   - has_many :issues,
31   - foreign_key: :author_id,
32   - dependent: :destroy
33   -
34   - has_many :notes,
35   - foreign_key: :author_id,
36   - dependent: :destroy
37   -
38   - has_many :assigned_issues,
39   - class_name: "Issue",
40   - foreign_key: :assignee_id,
41   - dependent: :destroy
42   -
43   - has_many :merge_requests,
44   - foreign_key: :author_id,
45   - dependent: :destroy
46   -
47   - has_many :assigned_merge_requests,
48   - class_name: "MergeRequest",
49   - foreign_key: :assignee_id,
50   - dependent: :destroy
51   -
52   - validates :projects_limit,
53   - presence: true,
54   - numericality: {greater_than_or_equal_to: 0}
  21 + has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
  22 + has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
  23 + has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
  24 + has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy
55 25  
56 26 validates :bio, length: { within: 0..255 }
57   -
58 27 validates :extern_uid, :allow_blank => true, :uniqueness => {:scope => :provider}
59   -
60   - before_save :ensure_authentication_token
61   - alias_attribute :private_token, :authentication_token
  28 + validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
62 29  
63 30 scope :not_in_project, lambda { |project| where("id not in (:ids)", ids: project.users.map(&:id) ) }
64 31 scope :admins, where(admin: true)
... ... @@ -66,6 +33,8 @@ class User &lt; ActiveRecord::Base
66 33 scope :active, where(blocked: false)
67 34  
68 35 before_validation :generate_password, on: :create
  36 + before_save :ensure_authentication_token
  37 + alias_attribute :private_token, :authentication_token
69 38  
70 39 def generate_password
71 40 if self.force_random_password
... ... @@ -107,17 +76,18 @@ class User &lt; ActiveRecord::Base
107 76 where("name like :query or email like :query", query: "%#{query}%")
108 77 end
109 78 end
  79 +
110 80 # == Schema Information
111 81 #
112 82 # Table name: users
113 83 #
114   -# id :integer(4) not null, primary key
  84 +# id :integer not null, primary key
115 85 # email :string(255) default(""), not null
116 86 # encrypted_password :string(128) default(""), not null
117 87 # reset_password_token :string(255)
118 88 # reset_password_sent_at :datetime
119 89 # remember_created_at :datetime
120   -# sign_in_count :integer(4) default(0)
  90 +# sign_in_count :integer default(0)
121 91 # current_sign_in_at :datetime
122 92 # last_sign_in_at :datetime
123 93 # current_sign_in_ip :string(255)
... ... @@ -125,14 +95,18 @@ end
125 95 # created_at :datetime not null
126 96 # updated_at :datetime not null
127 97 # name :string(255)
128   -# admin :boolean(1) default(FALSE), not null
129   -# projects_limit :integer(4) default(10)
  98 +# admin :boolean default(FALSE), not null
  99 +# projects_limit :integer default(10)
130 100 # skype :string(255) default(""), not null
131 101 # linkedin :string(255) default(""), not null
132 102 # twitter :string(255) default(""), not null
133 103 # authentication_token :string(255)
134   -# dark_scheme :boolean(1) default(FALSE), not null
135   -# theme_id :integer(4) default(1), not null
  104 +# dark_scheme :boolean default(FALSE), not null
  105 +# theme_id :integer default(1), not null
136 106 # bio :string(255)
137   -# blocked :boolean(1) default(FALSE), not null
  107 +# blocked :boolean default(FALSE), not null
  108 +# failed_attempts :integer default(0)
  109 +# locked_at :datetime
  110 +# extern_uid :string(255)
  111 +# provider :string(255)
138 112 #
... ...
app/models/users_project.rb
... ... @@ -88,15 +88,15 @@ class UsersProject &lt; ActiveRecord::Base
88 88 self.class.access_roles.invert[self.project_access]
89 89 end
90 90 end
  91 +
91 92 # == Schema Information
92 93 #
93 94 # Table name: users_projects
94 95 #
95   -# id :integer(4) not null, primary key
96   -# user_id :integer(4) not null
97   -# project_id :integer(4) not null
  96 +# id :integer not null, primary key
  97 +# user_id :integer not null
  98 +# project_id :integer not null
98 99 # created_at :datetime not null
99 100 # updated_at :datetime not null
100   -# project_access :integer(4) default(0), not null
  101 +# project_access :integer default(0), not null
101 102 #
102   -
... ...
app/models/web_hook.rb
... ... @@ -6,34 +6,31 @@ class WebHook &lt; ActiveRecord::Base
6 6 # HTTParty timeout
7 7 default_timeout 10
8 8  
9   - validates :url,
10   - presence: true,
11   - format: {
12   - with: URI::regexp(%w(http https)),
13   - message: "should be a valid url" }
  9 + validates :url, presence: true,
  10 + format: { with: URI::regexp(%w(http https)), message: "should be a valid url" }
14 11  
15 12 def execute(data)
16 13 parsed_url = URI.parse(url)
17 14 if parsed_url.userinfo.blank?
18 15 WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
19 16 else
20   - post_url = url.gsub(parsed_url.userinfo+"@", "")
  17 + post_url = url.gsub("#{parsed_url.userinfo}@", "")
21 18 WebHook.post(post_url,
22 19 body: data.to_json,
23   - headers: { "Content-Type" => "application/json" },
  20 + headers: {"Content-Type" => "application/json"},
24 21 basic_auth: {username: parsed_url.user, password: parsed_url.password})
25 22 end
26 23 end
27   -
28 24 end
  25 +
29 26 # == Schema Information
30 27 #
31 28 # Table name: web_hooks
32 29 #
33   -# id :integer(4) not null, primary key
  30 +# id :integer not null, primary key
34 31 # url :string(255)
35   -# project_id :integer(4)
  32 +# project_id :integer
36 33 # created_at :datetime not null
37 34 # updated_at :datetime not null
  35 +# type :string(255) default("ProjectHook")
38 36 #
39   -
... ...
app/models/wiki.rb
... ... @@ -32,17 +32,17 @@ class Wiki &lt; ActiveRecord::Base
32 32 end
33 33 end
34 34 end
  35 +
35 36 # == Schema Information
36 37 #
37 38 # Table name: wikis
38 39 #
39   -# id :integer(4) not null, primary key
  40 +# id :integer not null, primary key
40 41 # title :string(255)
41 42 # content :text
42   -# project_id :integer(4)
  43 +# project_id :integer
43 44 # created_at :datetime not null
44 45 # updated_at :datetime not null
45 46 # slug :string(255)
46   -# user_id :integer(4)
  47 +# user_id :integer
47 48 #
48   -
... ...
config/database.yml.example
... ... @@ -9,12 +9,11 @@ production:
9 9 pool: 5
10 10 username: root
11 11 password: "secure password"
  12 + # host: localhost
12 13 # socket: /tmp/mysql.sock
13 14  
14   -
15   -#
16   -# Development specific
17 15 #
  16 +# Development specific
18 17 #
19 18 development:
20 19 adapter: mysql2
... ... @@ -38,6 +37,3 @@ test: &amp;test
38 37 username: root
39 38 password: "secure password"
40 39 # socket: /tmp/mysql.sock
41   -
42   -cucumber:
43   - <<: *test
... ...
config/database.yml.mysql
... ... @@ -9,12 +9,11 @@ production:
9 9 pool: 5
10 10 username: root
11 11 password: "secure password"
  12 + # host: localhost
12 13 # socket: /tmp/mysql.sock
13 14  
14   -
15   -#
16   -# Development specific
17 15 #
  16 +# Development specific
18 17 #
19 18 development:
20 19 adapter: mysql2
... ... @@ -38,6 +37,3 @@ test: &amp;test
38 37 username: root
39 38 password:
40 39 # socket: /tmp/mysql.sock
41   -
42   -cucumber:
43   - <<: *test
... ...
config/database.yml.sqlite
... ... @@ -12,11 +12,8 @@ production:
12 12 pool: 5
13 13 timeout: 5000
14 14  
15   -
16   -#
17   -# Development specific
18   -#
19 15 #
  16 +# Development specific
20 17 #
21 18 development:
22 19 adapter: sqlite3
... ... @@ -32,6 +29,3 @@ test: &amp;test
32 29 database: db/test.sqlite3
33 30 pool: 5
34 31 timeout: 5000
35   -
36   -cucumber:
37   - <<: *test
... ...