I have an action in my app called "like" that is an action inside the book controller, ie, my Devise users can "like" a book which adds it to their profile.
In CanCan, I want users with role=="author" to be able to create, update, delete their own books, which works fine. The problem is that I want any user to be able to "like" any book. When I add that ability, I am letting users "manage" all books - how do I restrict it so all users can Like/Unlike books, but author users can manage books that they own?
Any tips are appreciated!
ability.rb
def initialize(user)
# Guest User
can :read, :all
unless user
can :read, :all
else
# All registered users
can :read, :all
can :manage, Like
can :manage, Book
# Authors
if user.role == 'author'
can :read, :all
can :create, Recommendation
can :manage, Recommendation do |r|
user && r.user == user
end
can :create, Book
can :manage, Book do |b|
user && b.user == user
end
# Admins
elsif user.role == 'admin'
can :manage, :all
end
end
end
likes controller
before_action :set_project
load_and_authorize_resource
def create
if Like.create(liked: @book, user: current_user)
redirect_to @book, notice: 'Book has been favorited'
else
redirect_to @book, alert: 'Something went wrong'
end
end
def destroy
Like.where(liked_id: @book.id, user_id: current_user.id).first.destroy
redirect_to @book, notice: 'Book is no longer in favorites'
end
private
def set_project
@book = Book.find(params[:book_id] || params[:id])
end
def like_params
params.require(:like).permit(:user_id, :book_id)
end
end
book show
<% unless current_user.liked_books.exists?(id: @book.id) %>
<%= link_to 'Add to likes', like_path, method: :post %>
<% else %>
<%= link_to 'Remove from likes', like_path(@book), method: :delete %>
<% end %>