Rails 无法正常工作

Rails cancan not working properly

我正在尝试建立一个博客,其中将有 2 个用户管理员和普通 user.Admin 可以查看每个 post 和评论。而普通用户只能查看他的 post 和评论。我已经应用了我的逻辑,但它不起作用。在我的代码中,每个用户都可以相互查看 post 和我不想要的评论。我已将我的代码上传到 github
link


[ability.rb]

class Ability
  include CanCan::Ability
   def initialize(user)
        unless user
        else
          case user.roles
          when 'admin'
           can :manage, Post
           can :manage, Comment
         when 'user' 
           can :manage, Post, user_id: user.id
           can :manage, Comment, user_id: user.id
         end
        end


class PostsController < ApplicationController
    before_action :authenticate_user! 
    authorize_resource

    def index
        @posts = Post.all.order('created_at DESC')
    end

    def new
        @post = Post.new
    end

    def show
        @post = Post.find(params[:id])
    end

    def create
        @post = Post.new(post_params)
        @post.user = current_user

        if @post.save
            redirect_to @post
        else
            render 'new'
        end
    end

    def edit
        @post = Post.find(params[:id])
    end

    def update
        @post = Post.find(params[:id])

        if @post.update(params[:post].permit(:title, :body))
            redirect_to @post
        else
            render 'edit'
        end
    end

    def destroy
        @post = Post.find(params[:id])
        @post.destroy

        redirect_to posts_path
    end

    private

    def post_params
        params.require(:post).permit(:title, :body)
    end
end


[comment_controller]

class CommentsController < ApplicationController
          authorize_resource

    def create
        @post = Post.find(params[:post_id])
        @comment = @post.comments.build(params[:comment].permit(:name, :body))
         @comment.user = current_user
         @comment.save
        redirect_to post_path(@post)
    end

    def destroy
        @post = Post.find(params[:post_id])
        @comment = @post.comments.find(params[:id])
        @comment.destroy

        redirect_to post_path(@post)
    end
end


[user.rb]

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
      has_many :posts
      has_many :comments
end


[post.rb]

class Post < ActiveRecord::Base
    has_many :comments, dependent: :destroy
    validates :title, presence: true, length: {minimum: 5}
    validates :body,  presence: true
    belongs_to :user
end


[comment.rb]

class Comment < ActiveRecord::Base
  belongs_to :post
  belongs_to :user

end

希望您已将每个用户的角色维护为管理员或普通用户。

你可以试试这个

in ability.rb

include CanCan::Ability

  def initialize(user)

     case user.role

     when User::Roles::ADMIN
       can :manage, :all
     end

     when User::Roles::USER
       can :create, Comment, :user_id => user.id
     end
  end

希望这会有所帮助

很可能您只需要添加 :read 指令和 :manage 来禁止用户查看其他用户的帖子。

像这样:

class Ability
  include CanCan::Ability
   def initialize(user)
        unless user
        else
          case user.roles
          when 'admin'
           can :manage, Post
           can :manage, Comment
         when 'user' 
           can :manage, Post, user_id: user.id
           can :manage, Comment, user_id: user.id
           can :read, Post, user_id: user.id
           can :read, Comment, user_id: user.id
       end
     end
  end
end

请参考此页:https://github.com/ryanb/cancan/wiki/defining-abilities

首先...

CanCan不再维护; CanCanCan 应添加到您的 Gemfile:

#Gemfile
gem "cancancan"

--

您将能够使用以下内容:

#app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    case user.roles
       when "admin" #-> use double quotes for evaluating strings
          can :manage, [Post, Comment]
       when "user"
          can :manage, [Post, Comment], user_id: user.id
       end
  end
end

--

您还需要确保您正在调用 authorize!

虽然 authorize_resource 很好,但在您的情况下,您需要确保遵守惯例...

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
    authorize_resource :post
    authorize_resource :comment

    def create
        @post    = Post.find params[:post_id]
        @comment = @post.comments.new comment_params
        @comment.user = current_user
        @comment.save

        redirect_to @post
    end

    def destroy
        @post    = Post.find(params[:post_id])
        @comment = @post.comments.find params[:id]
        @comment.destroy

        redirect_to @post
    end

    private

    def comment_params
       params.require(:comment).permit(:name, :body)
    end
end