Commit 8a86fe7bb0785ea69e591fd287430eb5448ac64e
Committed by
Dmitriy Zaporozhets
1 parent
f6c482c0
Exists in
master
and in
4 other branches
Added UserTeam core models (team and m-t-m relationships) and updated other models
Showing
14 changed files
with
249 additions
and
29 deletions
Show diff stats
app/models/concerns/issuable.rb
... | ... | @@ -22,6 +22,7 @@ module Issuable |
22 | 22 | scope :opened, where(closed: false) |
23 | 23 | scope :closed, where(closed: true) |
24 | 24 | scope :of_group, ->(group) { where(project_id: group.project_ids) } |
25 | + scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) } | |
25 | 26 | scope :assigned, ->(u) { where(assignee_id: u.id)} |
26 | 27 | scope :recent, order("created_at DESC") |
27 | 28 | ... | ... |
app/models/project.rb
... | ... | @@ -33,28 +33,31 @@ class Project < ActiveRecord::Base |
33 | 33 | attr_accessor :error_code |
34 | 34 | |
35 | 35 | # Relations |
36 | - belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'" | |
36 | + belongs_to :creator, foreign_key: "creator_id", class_name: "User" | |
37 | + belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'" | |
37 | 38 | belongs_to :namespace |
38 | 39 | |
39 | - belongs_to :creator, | |
40 | - class_name: "User", | |
41 | - foreign_key: "creator_id" | |
42 | - | |
43 | - has_many :users, through: :users_projects | |
44 | - has_many :events, dependent: :destroy | |
45 | - has_many :merge_requests, dependent: :destroy | |
46 | - has_many :issues, dependent: :destroy, order: "closed, created_at DESC" | |
47 | - has_many :milestones, dependent: :destroy | |
48 | - has_many :users_projects, dependent: :destroy | |
49 | - has_many :notes, dependent: :destroy | |
50 | - has_many :snippets, dependent: :destroy | |
51 | - has_many :deploy_keys, dependent: :destroy, foreign_key: "project_id", class_name: "Key" | |
52 | - has_many :hooks, dependent: :destroy, class_name: "ProjectHook" | |
53 | - has_many :wikis, dependent: :destroy | |
54 | - has_many :protected_branches, dependent: :destroy | |
55 | 40 | has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id' |
56 | 41 | has_one :gitlab_ci_service, dependent: :destroy |
57 | 42 | |
43 | + has_many :events, dependent: :destroy | |
44 | + has_many :merge_requests, dependent: :destroy | |
45 | + has_many :issues, dependent: :destroy, order: "closed, created_at DESC" | |
46 | + has_many :milestones, dependent: :destroy | |
47 | + has_many :users_projects, dependent: :destroy | |
48 | + has_many :notes, dependent: :destroy | |
49 | + has_many :snippets, dependent: :destroy | |
50 | + has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id" | |
51 | + has_many :hooks, dependent: :destroy, class_name: "ProjectHook" | |
52 | + has_many :wikis, dependent: :destroy | |
53 | + has_many :protected_branches, dependent: :destroy | |
54 | + has_many :user_team_project_relationships, dependent: :destroy | |
55 | + | |
56 | + has_many :users, through: :users_projects | |
57 | + has_many :user_teams, through: :user_team_project_relationships | |
58 | + has_many :user_team_user_relationships, through: :user_teams | |
59 | + has_many :user_teams_members, through: :user_team_user_relationships | |
60 | + | |
58 | 61 | delegate :name, to: :owner, allow_nil: true, prefix: true |
59 | 62 | |
60 | 63 | # Validations |
... | ... | @@ -77,6 +80,8 @@ class Project < ActiveRecord::Base |
77 | 80 | # Scopes |
78 | 81 | scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) } |
79 | 82 | scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) } |
83 | + scope :without_team, ->(team) { where("id NOT IN (:ids)", ids: team.projects.map(&:id)) } | |
84 | + scope :in_team, ->(team) { where("id IN (:ids)", ids: team.projects.map(&:id)) } | |
80 | 85 | scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) } |
81 | 86 | scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") } |
82 | 87 | scope :personal, ->(user) { where(namespace_id: user.namespace_id) } | ... | ... |
app/models/user.rb
... | ... | @@ -45,18 +45,27 @@ class User < ActiveRecord::Base |
45 | 45 | attr_accessor :force_random_password |
46 | 46 | |
47 | 47 | # Namespace for personal projects |
48 | - has_one :namespace, class_name: "Namespace", foreign_key: :owner_id, conditions: 'type IS NULL', dependent: :destroy | |
49 | - has_many :groups, class_name: "Group", foreign_key: :owner_id | |
50 | - | |
51 | - has_many :keys, dependent: :destroy | |
52 | - has_many :users_projects, dependent: :destroy | |
53 | - has_many :issues, foreign_key: :author_id, dependent: :destroy | |
54 | - has_many :notes, foreign_key: :author_id, dependent: :destroy | |
55 | - has_many :merge_requests, foreign_key: :author_id, dependent: :destroy | |
56 | - has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy | |
57 | - has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC" | |
58 | - has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy | |
59 | - has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy | |
48 | + has_one :namespace, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace", conditions: 'type IS NULL' | |
49 | + | |
50 | + has_many :keys, dependent: :destroy | |
51 | + has_many :users_projects, dependent: :destroy | |
52 | + has_many :issues, dependent: :destroy, foreign_key: :author_id | |
53 | + has_many :notes, dependent: :destroy, foreign_key: :author_id | |
54 | + has_many :merge_requests, dependent: :destroy, foreign_key: :author_id | |
55 | + has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event" | |
56 | + has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue" | |
57 | + has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest" | |
58 | + | |
59 | + has_many :groups, class_name: "Group", foreign_key: :owner_id | |
60 | + has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC" | |
61 | + | |
62 | + has_many :projects, through: :users_projects | |
63 | + | |
64 | + has_many :user_team_user_relationships, dependent: :destroy | |
65 | + | |
66 | + has_many :user_teams, through: :user_team_user_relationships | |
67 | + has_many :user_team_project_relationships, through: :user_teams | |
68 | + has_many :team_projects, through: :user_team_project_relationships | |
60 | 69 | |
61 | 70 | validates :name, presence: true |
62 | 71 | validates :bio, length: { within: 0..255 } |
... | ... | @@ -80,6 +89,8 @@ class User < ActiveRecord::Base |
80 | 89 | scope :blocked, where(blocked: true) |
81 | 90 | scope :active, where(blocked: false) |
82 | 91 | scope :alphabetically, order('name ASC') |
92 | + scope :in_team, ->(team){ where(id: team.member_ids) } | |
93 | + scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) } | |
83 | 94 | |
84 | 95 | # |
85 | 96 | # Class methods | ... | ... |
... | ... | @@ -0,0 +1,87 @@ |
1 | +class UserTeam < ActiveRecord::Base | |
2 | + attr_accessible :name, :owner_id, :path | |
3 | + | |
4 | + belongs_to :owner, class_name: User | |
5 | + | |
6 | + has_many :user_team_project_relationships, dependent: :destroy | |
7 | + has_many :user_team_user_relationships, dependent: :destroy | |
8 | + | |
9 | + has_many :projects, through: :user_team_project_relationships | |
10 | + has_many :members, through: :user_team_user_relationships, source: :user | |
11 | + | |
12 | + validates :name, presence: true, uniqueness: true | |
13 | + validates :owner, presence: true | |
14 | + validates :path, uniqueness: true, presence: true, length: { within: 1..255 }, | |
15 | + format: { with: Gitlab::Regex.path_regex, | |
16 | + message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } | |
17 | + | |
18 | + scope :with_member, ->(user){ joins(:user_team_user_relationships).where(user_team_user_relationships: {user_id: user.id}) } | |
19 | + scope :created_by, ->(user){ where(owner_id: user) } | |
20 | + | |
21 | + class << self | |
22 | + def search query | |
23 | + where("name LIKE :query OR path LIKE :query", query: "%#{query}%") | |
24 | + end | |
25 | + | |
26 | + def global_id | |
27 | + 'GLN' | |
28 | + end | |
29 | + | |
30 | + def access_roles | |
31 | + UsersProject.access_roles | |
32 | + end | |
33 | + end | |
34 | + | |
35 | + def to_param | |
36 | + path | |
37 | + end | |
38 | + | |
39 | + def assign_to_projects(projects, access) | |
40 | + projects.each do |project| | |
41 | + assign_to_project(project, access) | |
42 | + end | |
43 | + end | |
44 | + | |
45 | + def assign_to_project(project, access) | |
46 | + Gitlab::UserTeamManager.assign(self, project, access) | |
47 | + end | |
48 | + | |
49 | + def resign_from_project(project) | |
50 | + Gitlab::UserTeamManager.resign(self, project) | |
51 | + end | |
52 | + | |
53 | + def add_members(users, access, group_admin) | |
54 | + users.each do |user| | |
55 | + add_member(user, access, group_admin) | |
56 | + end | |
57 | + end | |
58 | + | |
59 | + def add_member(user, access, group_admin) | |
60 | + Gitlab::UserTeamManager.add_member_into_team(self, user, access, group_admin) | |
61 | + end | |
62 | + | |
63 | + def remove_member(user) | |
64 | + Gitlab::UserTeamManager.remove_member_from_team(self, user) | |
65 | + end | |
66 | + | |
67 | + def max_project_access(project) | |
68 | + user_team_project_relationships.find_by_project_id(project).greatest_access | |
69 | + end | |
70 | + | |
71 | + def human_max_project_access(project) | |
72 | + self.class.access_roles.invert[max_project_access(project)] | |
73 | + end | |
74 | + | |
75 | + def default_projects_access(member) | |
76 | + user_team_user_relationships.find_by_user_id(member).permission | |
77 | + end | |
78 | + | |
79 | + def human_default_projects_access(member) | |
80 | + self.class.access_roles.invert[default_projects_access(member)] | |
81 | + end | |
82 | + | |
83 | + def admin?(member) | |
84 | + user_team_user_relationships.with_user(member).first.group_admin? | |
85 | + end | |
86 | + | |
87 | +end | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +class UserTeamProjectRelationship < ActiveRecord::Base | |
2 | + attr_accessible :greatest_access, :project_id, :user_team_id | |
3 | + | |
4 | + belongs_to :user_team | |
5 | + belongs_to :project | |
6 | + | |
7 | + validates :project, presence: true | |
8 | + validates :user_team, presence: true | |
9 | + validate :check_greatest_access | |
10 | + | |
11 | + scope :with_project, ->(project){ where(project_id: project.id) } | |
12 | + | |
13 | + private | |
14 | + | |
15 | + def check_greatest_access | |
16 | + errors.add(:base, :incorrect_access_code) unless correct_access? | |
17 | + end | |
18 | + | |
19 | + def correct_access? | |
20 | + return false if greatest_access.blank? | |
21 | + return true if UsersProject.access_roles.has_value?(greatest_access) | |
22 | + false | |
23 | + end | |
24 | +end | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +class UserTeamUserRelationship < ActiveRecord::Base | |
2 | + attr_accessible :group_admin, :permission, :user_id, :user_team_id | |
3 | + | |
4 | + belongs_to :user_team | |
5 | + belongs_to :user | |
6 | + | |
7 | + validates :user_team, presence: true | |
8 | + validates :user, presence: true | |
9 | + | |
10 | + scope :with_user, ->(user) { where(user_id: user.id) } | |
11 | + | |
12 | + def user_name | |
13 | + user.name | |
14 | + end | |
15 | +end | ... | ... |
app/models/users_project.rb
... | ... | @@ -39,7 +39,10 @@ class UsersProject < ActiveRecord::Base |
39 | 39 | scope :reporters, where(project_access: REPORTER) |
40 | 40 | scope :developers, where(project_access: DEVELOPER) |
41 | 41 | scope :masters, where(project_access: MASTER) |
42 | + | |
42 | 43 | scope :in_project, ->(project) { where(project_id: project.id) } |
44 | + scope :in_projects, ->(projects) { where(project_id: projects.map(&:id)) } | |
45 | + scope :with_user, ->(user) { where(user_id: user.id) } | |
43 | 46 | |
44 | 47 | class << self |
45 | 48 | ... | ... |
db/migrate/20121220064104_create_user_team_project_relationships.rb
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +class CreateUserTeamProjectRelationships < ActiveRecord::Migration | |
2 | + def change | |
3 | + create_table :user_team_project_relationships do |t| | |
4 | + t.integer :project_id | |
5 | + t.integer :user_team_id | |
6 | + t.integer :greatest_access | |
7 | + | |
8 | + t.timestamps | |
9 | + end | |
10 | + end | |
11 | +end | ... | ... |
db/migrate/20121220064453_create_user_team_user_relationships.rb
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +class CreateUserTeamUserRelationships < ActiveRecord::Migration | |
2 | + def change | |
3 | + create_table :user_team_user_relationships do |t| | |
4 | + t.integer :user_id | |
5 | + t.integer :user_team_id | |
6 | + t.boolean :group_admin | |
7 | + t.integer :permission | |
8 | + | |
9 | + t.timestamps | |
10 | + end | |
11 | + end | |
12 | +end | ... | ... |
db/schema.rb
... | ... | @@ -213,6 +213,31 @@ ActiveRecord::Schema.define(:version => 20130110172407) do |
213 | 213 | t.string "name" |
214 | 214 | end |
215 | 215 | |
216 | + create_table "user_team_project_relationships", :force => true do |t| | |
217 | + t.integer "project_id" | |
218 | + t.integer "user_team_id" | |
219 | + t.integer "greatest_access" | |
220 | + t.datetime "created_at", :null => false | |
221 | + t.datetime "updated_at", :null => false | |
222 | + end | |
223 | + | |
224 | + create_table "user_team_user_relationships", :force => true do |t| | |
225 | + t.integer "user_id" | |
226 | + t.integer "user_team_id" | |
227 | + t.boolean "group_admin" | |
228 | + t.integer "permission" | |
229 | + t.datetime "created_at", :null => false | |
230 | + t.datetime "updated_at", :null => false | |
231 | + end | |
232 | + | |
233 | + create_table "user_teams", :force => true do |t| | |
234 | + t.string "name" | |
235 | + t.string "path" | |
236 | + t.integer "owner_id" | |
237 | + t.datetime "created_at", :null => false | |
238 | + t.datetime "updated_at", :null => false | |
239 | + end | |
240 | + | |
216 | 241 | create_table "users", :force => true do |t| |
217 | 242 | t.string "email", :default => "", :null => false |
218 | 243 | t.string "encrypted_password", :default => "", :null => false | ... | ... |