Skip to content

Instantly share code, notes, and snippets.

@Thanatermesis
Created June 13, 2013 01:44
Show Gist options
  • Save Thanatermesis/5770648 to your computer and use it in GitHub Desktop.
Save Thanatermesis/5770648 to your computer and use it in GitHub Desktop.
This is an old patch for redmine to create subgroups feature, not works in recent redmine's
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index db56eff..06f9284 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -106,33 +106,33 @@ class GroupsController < ApplicationController
end
end
- def add_users
+ def add_principals
@group = Group.find(params[:id])
- users = User.find_all_by_id(params[:user_ids])
- @group.users << users if request.post?
+ principals = Principal.find_all_by_id(params[:user_ids]) - @group.parent_groups
+ @group.principals << principals if request.post?
respond_to do |format|
format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
format.js {
render(:update) {|page|
page.replace_html "tab-content-users", :partial => 'groups/users'
- users.each {|user| page.visual_effect(:highlight, "user-#{user.id}") }
+ principals.each {|principal| page.visual_effect(:highlight, "user-#{principal.id}") }
}
}
end
end
- def remove_user
+ def remove_principal
@group = Group.find(params[:id])
- @group.users.delete(User.find(params[:user_id])) if request.post?
+ @group.principals.delete(Principal.find(params[:user_id])) if request.post?
respond_to do |format|
format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
format.js { render(:update) {|page| page.replace_html "tab-content-users", :partial => 'groups/users'} }
end
end
- def autocomplete_for_user
+ def autocomplete_for_principal
@group = Group.find(params[:id])
- @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
+ @principals = Principal.active.not_in_group(@group).like(params[:q]).all(:limit => 100) - @group.parent_groups
render :layout => false
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 1b55c25..1817eb2 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -16,20 +16,25 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Group < Principal
- has_and_belongs_to_many :users, :after_add => :user_added,
- :after_remove => :user_removed
+ has_and_belongs_to_many :principals, :after_add => :principal_added,
+ :after_remove => :principal_removed
acts_as_customizable
validates_presence_of :lastname
validates_uniqueness_of :lastname, :case_sensitive => false
validates_length_of :lastname, :maximum => 30
-
+
+ named_scope :direct_parents, lambda {|group|
+ group_id = group.is_a?(Group) ? group.id : group.to_i
+ { :conditions => ["#{Group.table_name}.id IN (SELECT gp.group_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gp WHERE gp.principal_id = ?)", group_id] }
+ }
+
def to_s
lastname.to_s
end
- def user_added(user)
+ def principal_added(user)
members.each do |member|
next if member.project.nil?
user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
@@ -40,10 +45,19 @@ class Group < Principal
end
end
- def user_removed(user)
+ def principal_removed(user)
members.each do |member|
MemberRole.find(:all, :include => :member,
:conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
end
end
+
+ def parent_groups
+ direct_parents = Group.direct_parents(self).all
+ parent_groups = direct_parents
+ direct_parents.each do |direct_parent|
+ parent_groups += direct_parent.parent_groups
+ end
+ return parent_groups
+ end
end
diff --git a/app/models/member_role.rb b/app/models/member_role.rb
index 9c28d41..7ab4eed 100644
--- a/app/models/member_role.rb
+++ b/app/models/member_role.rb
@@ -44,8 +44,8 @@ class MemberRole < ActiveRecord::Base
def add_role_to_group_users
if member.principal.is_a?(Group)
- member.principal.users.each do |user|
- user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
+ member.principal.principals.each do |principal|
+ user_member = Member.find_by_project_id_and_user_id(member.project_id, principal.id) || Member.new(:project_id => member.project_id, :user_id => principal.id)
user_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
user_member.save!
end
diff --git a/app/models/principal.rb b/app/models/principal.rb
index b3e07dd..cfd4021 100644
--- a/app/models/principal.rb
+++ b/app/models/principal.rb
@@ -21,6 +21,8 @@ class Principal < ActiveRecord::Base
has_many :members, :foreign_key => 'user_id', :dependent => :destroy
has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
has_many :projects, :through => :memberships
+ has_and_belongs_to_many :groups, :after_add => Proc.new {|principal, group| group.principal_added(principal)},
+ :after_remove => Proc.new {|principal, group| group.principal_removed(principal)}
# Groups and active users
named_scope :active, :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status = 1)"
@@ -46,6 +48,15 @@ class Principal < ActiveRecord::Base
principal.class.name <=> self.class.name
end
end
+
+ named_scope :in_group, lambda {|group|
+ group_id = group.is_a?(Group) ? group.id : group.to_i
+ { :conditions => ["#{Principal.table_name}.id IN (SELECT gu.principal_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
+ }
+ named_scope :not_in_group, lambda {|group|
+ group_id = group.is_a?(Group) ? group.id : group.to_i
+ { :conditions => ["#{Principal.table_name}.id NOT IN (SELECT gu.principal_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gu WHERE gu.group_id = ?) AND #{Principal.table_name}.id <> ?", group_id, group_id] }
+ }
protected
diff --git a/app/models/user.rb b/app/models/user.rb
index c06a907..7099ce8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -43,8 +43,6 @@ class User < Principal
['none', :label_user_mail_option_none]
]
- has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
- :after_remove => Proc.new {|user, group| group.user_removed(user)}
has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
has_many :changesets, :dependent => :nullify
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
@@ -76,15 +74,6 @@ class User < Principal
before_destroy :remove_references_before_destroy
- named_scope :in_group, lambda {|group|
- group_id = group.is_a?(Group) ? group.id : group.to_i
- { :conditions => ["#{User.table_name}.id IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
- }
- named_scope :not_in_group, lambda {|group|
- group_id = group.is_a?(Group) ? group.id : group.to_i
- { :conditions => ["#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
- }
-
def before_create
self.mail_notification = Setting.default_notification_option if self.mail_notification.blank?
true
diff --git a/app/views/groups/_users.html.erb b/app/views/groups/_users.html.erb
index d7c462e..88538a5 100644
--- a/app/views/groups/_users.html.erb
+++ b/app/views/groups/_users.html.erb
@@ -1,16 +1,16 @@
<div class="splitcontentleft">
-<% if @group.users.any? %>
+<% if @group.principals.any? %>
<table class="list users">
<thead><tr>
- <th><%= l(:label_user) %></th>
+ <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
<th style="width:15%"></th>
</tr></thead>
<tbody>
- <% @group.users.sort.each do |user| %>
+ <% @group.principals.sort.each do |user| %>
<tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
<td class="user"><%= link_to_user user %></td>
<td class="buttons">
- <%= link_to_remote l(:button_delete), { :url => { :controller => 'groups', :action => 'remove_user', :id => @group, :user_id => user },
+ <%= link_to_remote l(:button_delete), { :url => { :controller => 'groups', :action => 'remove_principal', :id => @group, :user_id => user },
:method => :post },
:class => 'icon icon-del' %>
</td>
@@ -24,21 +24,21 @@
</div>
<div class="splitcontentright">
-<% users = User.active.not_in_group(@group).all(:limit => 100) %>
-<% if users.any? %>
- <% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_users', :id => @group}, :method => :post) do |f| %>
+<% principals = Principal.active.not_in_group(@group).all(:limit => 100) - @group.parent_groups %>
+<% if principals.any? %>
+ <% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_principals', :id => @group}, :method => :post) do |f| %>
<fieldset><legend><%=l(:label_user_new)%></legend>
- <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
+ <p><%= label_tag "user_search", l(:label_principal_search) %><%= text_field_tag 'user_search', nil %></p>
<%= observe_field(:user_search,
:frequency => 0.5,
- :update => :users,
- :url => { :controller => 'groups', :action => 'autocomplete_for_user', :id => @group },
+ :update => :principals,
+ :url => { :controller => 'groups', :action => 'autocomplete_for_principal', :id => @group },
:with => 'q')
%>
- <div id="users">
- <%= principals_check_box_tags 'user_ids[]', users %>
+ <div id="principals">
+ <%= principals_check_box_tags 'user_ids[]', principals %>
</div>
<p><%= submit_tag l(:button_add) %></p>
diff --git a/app/views/groups/autocomplete_for_principal.html.erb b/app/views/groups/autocomplete_for_principal.html.erb
new file mode 100644
index 0000000..5f8163d
--- /dev/null
+++ b/app/views/groups/autocomplete_for_principal.html.erb
@@ -0,0 +1 @@
+<%= principals_check_box_tags 'user_ids[]', @principals %>
diff --git a/app/views/groups/autocomplete_for_user.html.erb b/app/views/groups/autocomplete_for_user.html.erb
deleted file mode 100644
index de1b007..0000000
--- a/app/views/groups/autocomplete_for_user.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= principals_check_box_tags 'user_ids[]', @users %>
diff --git a/app/views/groups/index.html.erb b/app/views/groups/index.html.erb
index 48b9ab4..2ab073e 100644
--- a/app/views/groups/index.html.erb
+++ b/app/views/groups/index.html.erb
@@ -15,7 +15,7 @@
<% @groups.each do |group| %>
<tr class="<%= cycle 'odd', 'even' %>">
<td><%= link_to h(group), :action => 'edit', :id => group %></td>
- <td align="center"><%= group.users.size %></td>
+ <td align="center"><%= group.principals.size %></td>
<td class="buttons"><%= link_to l(:button_delete), group, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %></td>
</tr>
<% end %>
diff --git a/app/views/groups/show.html.erb b/app/views/groups/show.html.erb
index 02927eb..3011581 100644
--- a/app/views/groups/show.html.erb
+++ b/app/views/groups/show.html.erb
@@ -1,7 +1,7 @@
<h2><%= link_to l(:label_group_plural), groups_path %> &#187; <%=h @group %></h2>
<ul>
-<% @group.users.each do |user| %>
- <li><%=h user %></li>
+<% @group.principals.each do |principal| %>
+ <li><%=h principal %></li>
<% end %>
</ul>
diff --git a/db/migrate/20110428091629_refactor_group_users_as_principals.rb b/db/migrate/20110428091629_refactor_group_users_as_principals.rb
new file mode 100644
index 0000000..42f66e5
--- /dev/null
+++ b/db/migrate/20110428091629_refactor_group_users_as_principals.rb
@@ -0,0 +1,15 @@
+class RefactorGroupUsersAsPrincipals < ActiveRecord::Migration
+ def self.up
+ rename_table :groups_users, :groups_principals
+ change_table :groups_principals do |t|
+ t.rename :user_id, :principal_id
+ end
+ end
+
+ def self.down
+ rename_table :groups_principals, :groups_users
+ change_table :groups_principals do |t|
+ t.rename :principal_id, :user_id
+ end
+ end
+end
@intfrr
Copy link

intfrr commented Aug 19, 2015

By recent versions, you mean version 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment