From 7d67986e8ba9e5cbd2b015e71f6de968a6f24179 Mon Sep 17 00:00:00 2001 From: Bryan Larsen Date: Mon, 3 Jun 2013 16:38:28 +0200 Subject: [PATCH] granting-write-access-to-others It's not enough just to allow others to view your projects, you need to allow some people to make changes, too. The goal of this part of the tutorial is to add a "Contributor" checkbox next to each person in the side-bar. Implementing this is left as an exercise for the reader. The steps are: 1. Add a boolean `contributor` field to the `ProjectMembership` model. 2. Modify the permissions of stories and tasks so that users with `contributor=true` on their project membership have update permission for the project. 3. Use the `` tag to create an ajax editor for the `contributor` field in the ProjectMembership card. That's all the hints we're going to give you for this one -- good luck! Ok, one more hint, here's some associations that might be handy in the Project model: has_many :contributor_memberships, :class_name => "ProjectMembership", :scope => :contributor has_many :contributors, :through => :contributor_memberships, :source => :user {: .ruby} And a helper method that might come in handy when implementing your permission methods: def accepts_changes_from?(user) user.administrator? || user == owner || user.in?(contributors) end {: .ruby} --- app/models/project.rb | 10 +++++++++- app/models/project_membership.rb | 1 + app/views/taglibs/front_site.dryml | 9 +++++++++ db/migrate/20130109032331_project_contributors.rb | 9 +++++++++ db/schema.rb | 3 ++- 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20130109032331_project_contributors.rb diff --git a/app/models/project.rb b/app/models/project.rb index d1b32df..7d86910 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -19,6 +19,14 @@ class Project < ActiveRecord::Base belongs_to :owner, :class_name => "User", :creator => true, :inverse_of => :projects + has_many :contributor_memberships, :class_name => "ProjectMembership", :scope => :contributor + has_many :contributors, :through => :contributor_memberships, :source => :user + + # permission helper + def accepts_changes_from?(user) + user.administrator? || user == owner || user.in?(contributors) + end + # --- Permissions --- # def create_permitted? @@ -26,7 +34,7 @@ def create_permitted? end def update_permitted? - acting_user.administrator? || (owner_is?(acting_user) && !owner_changed?) + accepts_changes_from?(acting_user) && !owner_changed? end def destroy_permitted? diff --git a/app/models/project_membership.rb b/app/models/project_membership.rb index 143d1b7..853cd0b 100644 --- a/app/models/project_membership.rb +++ b/app/models/project_membership.rb @@ -3,6 +3,7 @@ class ProjectMembership < ActiveRecord::Base hobo_model # Don't put anything above this fields do + contributor :boolean, :default => false timestamps end attr_accessible diff --git a/app/views/taglibs/front_site.dryml b/app/views/taglibs/front_site.dryml index 45ab983..fd2976e 100644 --- a/app/views/taglibs/front_site.dryml +++ b/app/views/taglibs/front_site.dryml @@ -31,3 +31,12 @@ + + + + + Contributor? + + + + diff --git a/db/migrate/20130109032331_project_contributors.rb b/db/migrate/20130109032331_project_contributors.rb new file mode 100644 index 0000000..d7423c2 --- /dev/null +++ b/db/migrate/20130109032331_project_contributors.rb @@ -0,0 +1,9 @@ +class ProjectContributors < ActiveRecord::Migration + def self.up + add_column :project_memberships, :contributor, :boolean, :default => false + end + + def self.down + remove_column :project_memberships, :contributor + end +end diff --git a/db/schema.rb b/db/schema.rb index e5d0419..1ea68ed 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,14 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130109030838) do +ActiveRecord::Schema.define(:version => 20130109032331) do create_table "project_memberships", :force => true do |t| t.datetime "created_at" t.datetime "updated_at" t.integer "project_id" t.integer "user_id" + t.boolean "contributor", :default => false end add_index "project_memberships", ["project_id"], :name => "index_project_memberships_on_project_id"