Diff
Modified: trunk/app/controllers/group_announcements_controller.rb (2473 => 2474)
--- trunk/app/controllers/group_announcements_controller.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/controllers/group_announcements_controller.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -109,7 +109,7 @@
def check_admin
- unless @group.owner?(current_user.id)
+ unless @group.administrator?(current_user.id)
error("Only group administrators are allowed to create new announcements")
return false
end
@@ -148,7 +148,7 @@
end
when "edit","update","destroy"
# only owner of the group can destroy the announcement
- unless @group.owner?(current_user.id)
+ unless ((@announcement.user == current_user) || (@group.owner?(current_user.id)))
not_auth = true;
raise ActiveRecord::RecordNotFound, "You don't have permissions to perform this action"
end
Modified: trunk/app/controllers/memberships_controller.rb (2473 => 2474)
--- trunk/app/controllers/memberships_controller.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/controllers/memberships_controller.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -22,22 +22,63 @@
group = Network.find(@membership.network_id)
invite = @membership.is_invite?
- from_id = invite ? @membership.user_id : group.user_id
- to_id = invite ? group.user_id : @membership.user_id
- subject = User.find(from_id).name + " has accepted your membership " + (invite ? "invite" : "request") + " for '" + group.title + "' group"
- body = "<strong><i>Personal message from " + (invite ? "user" : "group admin") + ":</i></strong><hr/>"
+ personal_message = "NONE"
if params[:accept_msg] && !params[:accept_msg].blank?
- body += ae_some_html(params[:accept_msg])
+ personal_message = ae_some_html(params[:accept_msg])
+ end
+
+ # the messages will appear as 'deleted-by-sender', because the owner of the account effectively didn't send it,
+ # so there is no reason for showing this message in their 'sent messages' folder
+
+ if invite
+ from = User.find(@membership.user_id)
+
+ subject = "Invitation to '" + group.title + "' accepted"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has accepted an invitation to join <%= title(group) %> group.
+<br/>
+<br/>
+<strong><i>Personal message from user:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ group.administrators(true).each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
else
- body += "NONE"
+ from = current_user
+
+ subject = "Membership to '" + group.title + "' accepted"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has accepted your request to join <%= title(group) %> group.
+<br/>
+<br/>
+<strong><i>Personal message from <%= name(from) %>:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ send_action_message(from.id, @membership.user_id, subject, body)
+
+ subject = "Membership to '" + group.title + "' accepted"
+ body = render_to_string :locals => { :from => from, :other => @membership.user_id, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has accepted a request by <%= name(other) %> to join <%= title(group) %> group.
+<br/>
+<br/>
+<strong><i>Personal message from <%= name(from) %> to user:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ group.administrators(true).select{|admin| admin.id != from.id}.each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
end
- body += "<hr/>"
-
- # the message will appear as 'deleted-by-sender', because the owner of the account effectively didn't send it,
- # so there is no reason for showing this message in their 'sent messages' folder
- message = Message.new( :from => from_id, :to => to_id, :subject => subject, :body => body, :reply_id => nil, :read_at => nil, :deleted_by_sender => true )
- message.save
-
+
respond_to do |format|
if @membership.accept!
flash[:notice] = 'Membership was successfully accepted.'
@@ -175,57 +216,110 @@
# DELETE /memberships/1
def destroy
network_id = @membership.network_id
+ from = current_user
# a notification message will be delivered to the the requestor anyway;
# it may contain a personal note, if any was supplied
group = Network.find(network_id)
invite = @membership.is_invite?
rejection = (@membership.network_established_at.nil? || @membership.user_established_at.nil?) ? true : false
+
+ personal_message = "NONE"
+ if params[:reject_msg] && !params[:reject_msg].blank?
+ personal_message = ae_some_html(params[:reject_msg])
+ end
# the same method ('destroy') works when membership is rejected
# or removed after being accepted previously
if rejection
# if this is rejection, then just group admin can do this action, so
# the message would go from group admin to the requesting-user
- from_id = invite ? @membership.user_id : group.user_id
- to_id = invite ? group.user_id : @membership.user_id
-
- subject = User.find(from_id).name + " has rejected your membership " + (invite ? "invite" : "request") + " for '" + group.title + "' group"
- body = "<strong><i>Personal message from " + (invite ? "user" : "group admin") + ":</i></strong><hr/>"
-
- if params[:reject_msg] && !params[:reject_msg].blank?
- body += ae_some_html(params[:reject_msg])
+ if invite
+ subject = "Invitation to '" + group.title + "' rejected"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has rejected an invitation to join <%= title(group) %> group.
+<br/>
+<br/>
+<strong><i>Personal message from <%= name(from) %> to user:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ group.administrators(true).each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
else
- body += "NONE"
+ to_id = @membership.user_id
+
+ subject = "Membership to '" + group.title + "' rejected"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has rejected your request to join <%= title(group) %> group.
+<br/>
+<br/>
+<strong><i>Personal message from <%= name(from) %> to user:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ send_action_message(from.id, to_id, subject, body)
+
+ subject = "Membership to '" + group.title + "' rejected"
+ body = render_to_string :locals => { :from => from, :other => @membership.user_id, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has rejected the request by <%= name(other) %> to join <%= title(group) %> group."
+<br/>
+<strong><i>Personal message from <%= name(from) %> to user:</i></strong><hr/>
+<%= msg %>
+<hr/>
+EOM
+
+ group.administrators(true).select{|admin| admin.id != from.id}.each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
end
- body += "<hr/>"
+
else
# membership was cancelled, so the message goes from the current user
# (who can be either admin or a former group member) to the 'other side' of the membership;
# NB! subject and body should change accordingly!
- from_id = current_user.id
- from_user = User.find(from_id)
- to_id = (@membership.network.owner.id == from_id ? @membership.user_id : @membership.network.owner.id)
- if from_id == @membership.user_id
- subject = from_user.name + " has left the '" + group.title + "' group that you manage"
- body = "User: <a href=''>#{from_user.name}</a>" +
- "<br/><br/>If you want to contact this user directly, just reply to this message."
+ if current_user.id == @membership.user_id
+ subject = from.name + " has left the '" + group.title + "' group"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+User <%= name(from) %> has left <%= title(group) %> group.
+<br/>
+<br/>
+If you want to contact this user directly, just reply to this message.
+EOM
+
+ group.administrators(true).each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
else
- subject = from_user.name + " has removed you from '" + group.title + "' group"
- body = "Group: <a href=''networks', :action ="" 'show', :id => @membership.network_id}'>address@hidden</a>" +
- "<br/>Admin: <a href=''>address@hidden</a>" +
- "<br/><br/>If you want to contact the administrator of the group directly, just reply to this message."
+ subject = "You have been removed from '" + group.title + "' group"
+ body = render_to_string :locals => { :from => from, :group => group, :msg => personal_message },
+ :inline => <<EOM
+<%= name(from) %> has removed you from <%= title(group) %> group.
+<br/>
+<br/>
+If you want to contact the administrator directly, just reply to this message.
+EOM
+
+ send_action_message(from.id, @membership.user_id, subject, body)
+
+ subject = "User removed from '" + group.title + "' group"
+ body = render_to_string :locals => { :from => from, :other => @membership.user_id, :group => group, :msg => personal_message },
+ :inline => "<%= name(from) %> has removed <%= name(other) %> from <%= title(group) %> group."
+
+ group.administrators(true).select{|admin| admin.id != current_user.id}.each {|to|
+ send_action_message(from.id, to.id, subject, body)
+ }
end
end
-
- # the message will appear as 'deleted-by-sender', because the owner of the account effectively didn't send it,
- # so there is no reason for showing this message in their 'sent messages' folder
- message = Message.new( :from => from_id, :to => to_id, :subject => subject, :body => body, :reply_id => nil, :read_at => nil, :deleted_by_sender => true )
- message.save
-
-
@membership.destroy
respond_to do |format|
@@ -302,14 +396,14 @@
not_auth = true;
end
elsif @membership.network_established_at == nil
- unless @membership.network.owner.id == current_user.id && params[:user_id].to_i == @membership.network.owner.id
+ unless @membership.network.administrator?(current_user.id) # TODO: CHECK WHY?! && params[:user_id].to_i == @membership.network.owner.id
not_auth = true;
end
end
- when "show", "destroy"
+ when "show", "destroy", "update"
# Only the owner of the network OR the person who the membership is for can view/delete memberships;
# link - just user to whom the membership belongs
- unless (address@hidden, @membership.user_id].include? current_user.id) && @membership.user_id == params[:user_id].to_i
+ unless (@membership.network.administrator?(current_user.id) || @membership.user_id == current_user.id) && @membership.user_id == params[:user_id].to_i
not_auth = true
end
else
@@ -330,6 +424,11 @@
end
private
+
+ def send_action_message(from_id, to_id, subject, body)
+ message = Message.new(:from => from_id, :to => to_id, :subject => subject, :body => body, :reply_id => nil, :read_at => nil, :deleted_by_sender => true )
+ message.save
+ end
def error(notice, message, attr=:id)
flash[:error] = notice
Modified: trunk/app/controllers/networks_controller.rb (2473 => 2474)
--- trunk/app/controllers/networks_controller.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/controllers/networks_controller.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -8,7 +8,8 @@
before_filter :find_networks, : [:all]
before_filter :find_network, : [:membership_request, :show, :tag]
- before_filter :find_network_auth, : [:invite, :membership_invite, :membership_invite_external, :edit, :update, :destroy]
+ before_filter :find_network_auth_admin, : [:invite, :membership_invite, :membership_invite_external]
+ before_filter :find_network_auth_owner, : [:edit, :update, :destroy]
# declare sweepers and which actions should invoke them
cache_sweeper :network_sweeper, : [ :create, :update, :destroy, :membership_request, :membership_invite, :membership_invite_external ]
@@ -440,14 +441,23 @@
end
end
- def find_network_auth
+ def find_network_auth_owner
begin
@network = Network.find(params[:id], :conditions => ["networks.user_id = ?", current_user.id], :include => [ :owner, :memberships ])
rescue ActiveRecord::RecordNotFound
+ error("Group not found (id not authorized)", "is invalid (not group adminsitrator)")
+ end
+ end
+
+ def find_network_auth_admin
+ begin
+ @network = Network.find(params[:id], :include => [ :owner, :memberships ])
+ raise unless @network.administrator?(current_user.id)
+ rescue ActiveRecord::RecordNotFound
error("Group not found (id not authorized)", "is invalid (not owner)")
end
end
-
+
private
def error(notice, message)
Modified: trunk/app/helpers/application_helper.rb (2473 => 2474)
--- trunk/app/helpers/application_helper.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/helpers/application_helper.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -770,6 +770,10 @@
return "famfamfam_silk/text_signature.png"
when "home"
return "famfamfam_silk/application_home.png"
+ when "make_group_admin"
+ return "famfamfam_silk/award_star_add.png"
+ when "remove_group_admin"
+ return "famfamfam_silk/award_star_delete.png"
else
return Conf.label_icons[method.to_s] if Conf.label_icons[method.to_s]
end
@@ -999,7 +1003,7 @@
if membership.user_established_at == nil
return membership.user_id == current_user.id
elsif membership.network_established_at == nil
- return current_user.id == membership.network.owner.id
+ return membership.network.administrator?(current_user.id)
end
else
return false
Modified: trunk/app/models/membership.rb (2473 => 2474)
--- trunk/app/models/membership.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/models/membership.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -10,9 +10,9 @@
validates_presence_of :user_id, :network_id
- validates_each :user_id do |model, attr, value|
- model.errors.add attr, "already member" if model.network.member? value
- end
+# validates_each :user_id do |model, attr, value|
+# model.errors.add attr, "already member" if model.network.member? value
+# end
def user_establish!
if self.user_established_at.nil?
Modified: trunk/app/models/network.rb (2473 => 2474)
--- trunk/app/models/network.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/models/network.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -143,6 +143,27 @@
return false
end
+ def administrators(incl_owner=true)
+ explicit_administrators = User.find(:all,
+ :select => "users.*",
+ :joins => "JOIN memberships m on (users.id = m.user_id)",
+ :conditions => [ "m.network_id=? AND m.administrator AND m.user_established_at IS NOT NULL AND m.network_established_at IS NOT NULL", id ],
+ :order => "GREATEST(m.user_established_at, m.network_established_at) DESC"
+ )
+ return incl_owner ? ( [owner] + explicit_administrators ) : explicit_administrators
+ end
+
+ def administrator?(userid)
+ # the owner is automatically an adminsitrator of the network
+ return true if owner? userid
+
+ administrators(false).each do |a|
+ return true if a.id.to_i == userid.to_i
+ end
+
+ return false
+ end
+
# Finds all the contributions that have been explicitly shared via Permissions
def shared_contributions
list = []
Modified: trunk/app/models/user.rb (2473 => 2474)
--- trunk/app/models/user.rb 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/models/user.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -432,16 +432,31 @@
:order => "created_at DESC",
:dependent => :destroy
- def networks_membership_requests_pending
+ def networks_membership_requests_pending(include_group_admin=false)
rtn = []
- networks_owned.each do |n|
+ networks_admined(include_group_admin).each do |n|
rtn.concat n.memberships_requested
end
return rtn
end
+ def networks_admined(include_group_admin=false)
+ rtn = []
+
+ rtn.concat(networks_owned)
+
+ if include_group_admin
+ rtn.concat Network.find(:all,
+ :select => "networks.*",
+ :joins => "JOIN memberships m ON (networks.id = m.network_id)",
+ :conditions => ["m.user_id=? AND m.user_established_at is NOT NULL AND m.network_established_at IS NOT NULL AND m.administrator", id])
+ end
+
+ return rtn
+ end
+
def networks_membership_invites_pending
rtn = []
Modified: trunk/app/views/gadgets/_user_monitor.rhtml (2473 => 2474)
--- trunk/app/views/gadgets/_user_monitor.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/gadgets/_user_monitor.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -88,7 +88,7 @@
</div>
<% end %>
- <% unless (membership_requests = current_user.networks_membership_requests_pending).empty? %>
+ <% unless (membership_requests = current_user.networks_membership_requests_pending(true)).empty? %>
<hr/>
<div>
<div class="title">
Modified: trunk/app/views/group_announcements/_table.rhtml (2473 => 2474)
--- trunk/app/views/group_announcements/_table.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/group_announcements/_table.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -30,7 +30,7 @@
</td>
<td class="actions" style="width: 80px;">
<%= icon "show", group_announcement_path(group, announcement), nil, nil, "View" %>
- <% if (current_user != 0) && (group.owner?(current_user.id)) %>
+ <% if (current_user != 0) && ((announcement.user==current_user) || (group.owner?(current_user.id))) %>
<%= icon('edit', edit_group_announcement_path(group, announcement), nil, nil, 'Edit') %>
<%= icon("destroy", group_announcement_path(group, announcement), "Delete", :confirm => "Are you sure you want to delete this announcement?", :method => :delete) %>
<% end %>
Modified: trunk/app/views/memberships/_table.rhtml (2473 => 2474)
--- trunk/app/views/memberships/_table.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/memberships/_table.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -20,12 +20,12 @@
<% for membership in collection %>
<% allow_approval = allow_membership_pending_approval(membership) %>
<tr class="<%= (odd_row = !odd_row) ? "odd_row" : "even_row" %>">
- <% if user %><td width="100"><%= "<b>" unless membership.accepted? %><%= contributor(membership.user_id, "User", true, 60) %><%= "</b>" unless membership.accepted? %></td><% end %>
+ <% if user %><td width="100"><%= "<b>" unless membership.accepted? %><%= contributor(membership.user_id, "User", true, 60) %><%= "</b>" unless membership.accepted? %><%= '<div style="text-align: left"><b>Group Admin</b></div>' if membership.network.administrator?(membership.user_id) %></td><% end %>
<% if network %><td width="100"><%= "<b>" unless membership.accepted? %><%= contributor(membership.network_id, "Network", true, 60) %><%= "</b>" unless membership.accepted? %></td><% end %>
<td><%= "<b>" unless membership.accepted? %><%=datetime membership.created_at, false %><%= "</b>" unless membership.accepted? %></td>
<td><%= "<b>" unless membership.accepted? %><%=datetime(membership.accepted_at, false) || "Pending" %><%= "</b>" unless membership.accepted? %></td>
<td class="actions">
- <% if my_page? membership.user.id or my_page? membership.network.owner.id %>
+ <% if my_page? membership.user.id or (logged_in? and membership.network.administrator?(current_user.id)) %>
<%= icon "show", membership_path(membership.user_id, membership), nil, nil, "View" %>
<% if membership.accepted? %>
<%= icon "destroy", membership_path(membership.user_id, membership), nil, { :confirm => "Are you sure?", :method => :delete }, "Remove" %>
@@ -37,9 +37,17 @@
<%= icon "reject", membership_path(membership.user_id, membership), nil, :confirm => "Are you sure?", :method => :delete %>
<% end %>
<% end %>
+ <% if membership.accepted? %>
+ <% if membership.network.administrator?(membership.user_id) %>
+ <%= icon "remove_group_admin", membership_path(membership.user_id, membership)+'?membership[administrator]=0', nil, {:method => :put}, "Remove group admin status" %>
+ <% else %>
+ <%= icon "make_group_admin", membership_path(membership.user_id, membership)+'?membership[administrator]=1', nil, {:method => :put}, "Add
+group admin status" %>
+ <% end %>
+ <% end %>
</td>
</tr>
<% end %>
</table>
-<% end %>
\ No newline at end of file
+<% end %>
Modified: trunk/app/views/memberships/index.rhtml (2473 => 2474)
--- trunk/app/views/memberships/index.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/memberships/index.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -4,7 +4,7 @@
<h1>My Memberships</h1>
- <% memberships = @user.networks_membership_requests_pending %>
+ <% memberships = @user.networks_membership_requests_pending(true) %>
<div class="fold">
<div class="foldTitle">
<p>Pending requests sent by users who want to join your Groups <span style="color: red;">(<%= memberships.length %>)</span></p>
Modified: trunk/app/views/memberships/show.rhtml (2473 => 2474)
--- trunk/app/views/memberships/show.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/memberships/show.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -21,6 +21,9 @@
<% elsif (@membership.is_invite? && allow_approval) || (address@hidden && !allow_approval) %>
<% #= avatar @membership.network, 80 # will start to work once the group avatars are introduced %>
<% end %>
+ <% if (@membership.network.administrator?(@membership.user_id)) -%>
+ <div style="text-align: left"><b>Group Admin</b></div>
+ <% end -%>
</td>
<td style="line-height: 1.6; width: 85%;">
<% else %>
Modified: trunk/app/views/networks/_owner_box.rhtml (2473 => 2474)
--- trunk/app/views/networks/_owner_box.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/networks/_owner_box.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -1,7 +1,7 @@
<div class="contribution_section_box">
<p class="heading">
- <%= info_icon_with_tooltip("The administrator is the person who manages this group on #{Conf.sitename} (which means they allow/reject/invite other users).") %>
- Administrator
+ <%= info_icon_with_tooltip("The owner is the person who manages this group on #{Conf.sitename}. The owner and the group's administrators are able to allow/reject/invite other users).") %>
+ Owner
</p>
<p>
<center>
Modified: trunk/app/views/networks/show.rhtml (2473 => 2474)
--- trunk/app/views/networks/show.rhtml 2010-07-15 13:40:39 UTC (rev 2473)
+++ trunk/app/views/networks/show.rhtml 2010-07-15 15:59:22 UTC (rev 2474)
@@ -25,9 +25,11 @@
<% end %>
<% end %>
- <% if mine? @network %>
+ <% if @network.administrator?(current_user.id) %>
<li><%= icon('announcement', new_group_announcement_path(@network), 'Make a new Group Announcement', nil, 'Make a Group Announcement') -%></li>
<li><%= icon('network-invite', invite_group_path(@network), 'Invite People', nil, 'Invite People') -%></li>
+ <% end %>
+ <% if mine? @network %>
<li><%= icon('edit', edit_group_path(@network), 'Edit', nil, 'Edit Group') %></li>
<li><%= icon('destroy', group_path(@network), 'Delete Group', { :confirm => 'Are you sure?', :method => :delete }, 'Delete Group') %></li>
<% end %>
@@ -105,12 +107,21 @@
<br/>
<div class="contribution_section_box">
+<% address@hidden(true) -%>
+<% address@hidden() - admins -%>
<p class="heading">
+ Administrators
+ <a name="group_members"></a>
+ </p>
+ <div>
+ <%= render :partial => "networks/members", :locals => { :collection => admins, :size => 60 } %>
+ </div>
+ <p class="heading">
Members
<a name="group_members"></a>
</p>
<div>
- <%= render :partial => "networks/members", :locals => { :collection => @network.members(true), :size => 60 } %>
+ <%= render :partial => "networks/members", :locals => { :collection => others, :size => 60 } %>
</div>
</div>
@@ -198,7 +209,7 @@
</div>
</div>
-<% if mine? @network %>
+<% if @network.administrator?(current_user.id) %>
<% memberships = @network.memberships_accepted %>
<a name="manage_memberships"></a>
Added: trunk/db/migrate/088_add_group_admins.rb (0 => 2474)
--- trunk/db/migrate/088_add_group_admins.rb (rev 0)
+++ trunk/db/migrate/088_add_group_admins.rb 2010-07-15 15:59:22 UTC (rev 2474)
@@ -0,0 +1,10 @@
+
+class AddGroupAdmins < ActiveRecord::Migration
+ def self.up
+ add_column :memberships, :administrator, :boolean, :default => false
+ end
+
+ def self.down
+ remove_column :memberships, :administrator
+ end
+end
Property changes on: trunk/db/migrate/088_add_group_admins.rb
___________________________________________________________________
Added: svn:executable