2
votes

I am using Devise and CanCan to manage users and user-rights. What I want is: Ordinary users shall be able to update their own Posts. The most important Model is called Activity.

In the ability-model I have for ordinary members:

elsif user.role? :Member
   can :read, :all
   can :create, :all
   can :manage, Activity, :user_id=>user.id

(Thanks to Yuriy Goldshtrakh for the syntax of the third line)

In the index-view of the Activities, I have:

<% if can? :update, activity  %>
<br />
<%= link_to 'Update', edit_activity_path(activity) %>
<% end %>

<% if can? :delete, activity  %>
<%= link_to 'Delete', activity, :confirm => 'Really?', :method => :delete %>

<% end %>

This works: It only shows the update and the delete-link, if the Activity was created by the current member.

However, if the member updates the activity, the changes are not saved and the member is not sent back to the activity - as he/she should be after a successful update.

Here is the update-action in the Activities-controller:

  # PUT /activities/1.xml

def update

authorize! :update, @activity

@activity = Activity.find(params[:id])

respond_to do |format|
  if @activity.update_attributes(params[:activity])
    format.html { redirect_to(@activity, :notice => 'Activity was successfully updated.') }
    format.xml  { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml  { render :xml => @activity.errors, :status => :unprocessable_entity }
  end
end

end

The question is: Why ist the activity not updated correctly? I am grateful for all ideas!

3

3 Answers

3
votes

Swap line 1 and 3 of the ActivitiesController#update

def update
  @activity = Activity.find(params[:id])

  authorize! :update, @activity
  ...
end

You could also use the preferred way with Cancan: load_and_authorize_resource

1
votes

if your post and comments belong to the user you can do this

can :manage, [Post,Comment], :user_id=>user.id
0
votes

For example ability:

if user.role?(:author)
        can :create, Article
        can :update, Article do |article|
          article.try(:user) == user
        end
      end

Try do with this tutorial: Railscasts CanCan Maybe help