pwz2000
pwz2000

Reputation: 1395

if can? does not hide links on show.html

I have just installed cancan and I have run into a quick, small issue. I should be able to use if_can? to apply action to hide links. This is so only the information that was created by user can of course view the edit/delete links.

I haven't been able to find someone else who has had the same problem. If someone could take a look and help me out that would be greatly appreciated.

show.html:

<div id="photos">
    <% for photo in @gallery.photos %>
    <div class="photo">
        <%= image_tag photo.image_url(:thumb).to_s %>
        <div class="name"><%= photo.name %></div>
        <div class="actions">
            <% if can? :update, @photo %>
            <%= link_to "edit", edit_photo_path(photo) %> |
            <% end %>
            <% if can? :remove, @photo %>
            <%= link_to "remove", photo, :confirm => 'Are you sure?', :method => :delete %>
            <% end %>
        </div>
      </div>
    <% end %>
    <div class="clear"></div>
</div>

<p>
  <%= link_to "Add a Photo", new_photo_path(:gallery_id => @gallery) %>
|
  <%= link_to "Remove Gallery", @gallery, :confirm => 'Are you sure?', :method => :delete %> |
  <%= link_to "View Galleries", galleries_path %>
</p>

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    can :read, :all 
  end
end

Upvotes: 1

Views: 748

Answers (2)

Muhammad Suleman
Muhammad Suleman

Reputation: 2932

i also has passed through this problem. solution is simple in Ability.rb class do something as follows

class Ability
  include CanCan::Ability

  def initialize(user)
  user ||= User.new # guest user (not logged in)
  if user.role == "admin"
    can :update, Photo, :user_id => user.id
  end 
end 

then in index.html.erb do something as follows

<% @photos.each do |photo| %>
 <%if can? :update, photo %>
  <!-- hide your links and buttons here-->
 <%end%>
<%end%>

Note: in "<%if can? :update, photo %>" write "photo" instead of "Photo" or "@photo". because here photo is a veriable which will iterate through out the loop.

Upvotes: 0

Travis Pessetto
Travis Pessetto

Reputation: 3298

OK, each controller must be authorized. The easiest way to do this is to start at photo's and make sure that it cannot be deleted. You will need something like:

can :delete, Photo do |photo|
  question.try(:user) == user
end   

in your ability.rb. In your photo's controller you will need to put in either load_and_authorize_resource or authorize_resource.

Then in your view you want <%if can :remove, photo %> not <%if can :remove, @photo>. It seems odd to me you are trying to use @photo when you have <for photo in @gallery.photos %>

Upvotes: 1

Related Questions