Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails与cancan的授权_Ruby On Rails_Cancan - Fatal编程技术网

Ruby on rails Rails与cancan的授权

Ruby on rails Rails与cancan的授权,ruby-on-rails,cancan,Ruby On Rails,Cancan,我正在关注这一点 我试图授权用户只有当用户是管理员,他应该能够看到所有的帖子和评论,否则普通用户只能看到自己的帖子。我读过github页面,但相当混乱 [post_controller.rb] [评论.rb] class注释

我正在关注这一点 我试图授权用户只有当用户是管理员,他应该能够看到所有的帖子和评论,否则普通用户只能看到自己的帖子。我读过github页面,但相当混乱


[post_controller.rb]


[评论.rb]

class注释

[post.rb]

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

[user.rb]

class用户

[迁移]

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip
      t.timestamps
    end
    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
   end
end
classdeveliecCreateUsers

[迁移]

class CreateComments

[迁移]

class CreatePosts
以上是
能力
类的外观。您可以将替换为
if/else

--

您缺少对象的权限,特别是使用
can?
authorize
方法:

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
   def create
      @post = Post.find params[:post_id]
      @comment = @post.comments.new comment_params
      @comment.save if authorize! :create, @comment

      redirect_to @post
   end

   def destroy
     @post = Post.find params[:post_id]
     @comment = @post.comments.find params[:id]
     @comment.destroy if authorize! :destroy, @comment

     redirect_to @post
   end

   private

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

#app/controllers/posts_controller.rb
class PostsController < ApplicationController
   def show
      @post = Post.find params[:id]
   end
end

#app/views/posts/show.html.erb
<%= @post.title %>
<%= render @post.comments if can? :read, @post.comments %>
#app/controllers/comments_controller.rb
类CommentsController
1)在PostsController中更改此行,删除此条件:除了[索引,显示]。或者用户可以在未经授权的情况下查看页面

before_action :authenticate_user!
2) 使用此样式更改索引操作和其他操作。使用-当前用户

def index
  if current_user.has_role? :admin        
    @posts = Post.all.order('created_at DESC')
  else
    @posts = current_user.posts.order('created_at DESC')
  end
end

您似乎还没有与
post
comment
user
关系,您需要在其中确定用户是否拥有/创建了评论/帖子

运行:

然后添加关联关系:

post.rb

class Post < ActiveRecord::Base
  belongs_to :user
  # ..
end
现在,下一步是将登录用户与新创建的帖子/评论自动关联。通过控制器完成此操作:

posts\u controller.rb

class PostsController < ApplicationController
  authorize_resource
  # ..

  def create
    @post = Post.new(post_params)
    @post.user = current_user # I assume you have a variable current_user, or if you are using Devise current_user is already accessible

    if @post.save
      redirect_to @post
    else
      render :new
    end
  end
end
class CommentsController < Application
  authorize_resource
  # ..

  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.build(params[:comment].permit(:name, :body))
        #puts "hhhhhhhhhh#{@comment}"
    @comment.user = current_user # I assume you have a variable current_user, or if you are using Devise current_user is already accessible

    @comment.save

    redirect_to post_path(@post)
  end 
end
仅提供上述
功能的最后有用信息:

  • can:manage,Post,user\u-id:user.id

    这只是一个简写,等于:

    can [:show, :edit, :update, :destroy], Post, user_id: user.id
    can [:index, :new, :create], Post
    
    您会注意到,
    :index
    :new
    :create
    没有考虑
    用户id:user.id
    ,因为它们是
    :collection
    方法,而不是
    :member
    方法。更多信息

  • 如果您想要可读性和可定制性,您可以选择使用上面的较长版本,而不是速记
    :manage


    • 你可以用这种方式书写你的能力

      class Ability
        include CanCan::Ability
      
        def initialize(user)
            user ||= User.new # guest user (not logged in)
            case user.role
              when "admin"
                 can :manage, :all
              else
                 can :read, Post, :user_id => user.id
            end
        end
      end
      
      并且只需使用能力资源加载post的资源,以便它只加载当前用户的post(如果不是admin)

      class CommentsController < Application
        load_and_authorize_resource
          def index
           @posts = @posts
          end
      end
      
      class-commentscoontroller
      我需要一个用户登录,并且可以看到其唯一的帖子和评论。。。。但是管理员可以让每个人都发布comments@aniket,我假设您的Post和Comment模型都有一个名为
      user\u id
      的属性(或者您可以说是一个“列”),在您的
      Post
      Comment
      模型中都有一个
      属于:user
      。如果您没有这些,则需要先添加它们,因为这是您需要检查用户是否拥有帖子或评论的标识符。@aniket,我更新了答案,将用户分配到正在创建的帖子或评论。所以你知道是谁创造了它们。此用户将在您的
      能力中进行检查。rb
      只有在用户创建它们时才被授权。当然,这将更有帮助。但是如果您已经有了Post和Comment.thx的
      user\u id
      列,您就不必这样做了。这是我的最后一个问题,因为我是rails@Comment.user=current\u user的新手……那么这里的“user”是什么意思呢???它是我的用户表中的列名还是模型名,还是一些预定义的函数???
      before_action :authenticate_user!
      
      def index
        if current_user.has_role? :admin        
          @posts = Post.all.order('created_at DESC')
        else
          @posts = current_user.posts.order('created_at DESC')
        end
      end
      
      rails generate migration AddUserToPost user:belongs_to
      rails generate migration AddUserToComment user:belongs_to
      bundle exec rake db:migrate
      
      class Post < ActiveRecord::Base
        belongs_to :user
        # ..
      end
      
      class Comment < ActiveRecord::Base
        belongs_to :user
        # ..
      end
      
      class User < ActiveRecord::Base
        has_many :posts
        has_many :comments
        # ..
      end
      
      # rails console
      post = Post.find(1)
      post_owner = post.user
      
      comment = Comment.find(1)
      comment_owner = comment.user
      
      user = User.find(1)
      user_comments = user.comments
      user_posts = user.posts
      
      class PostsController < ApplicationController
        authorize_resource
        # ..
      
        def create
          @post = Post.new(post_params)
          @post.user = current_user # I assume you have a variable current_user, or if you are using Devise current_user is already accessible
      
          if @post.save
            redirect_to @post
          else
            render :new
          end
        end
      end
      
      class CommentsController < Application
        authorize_resource
        # ..
      
        def create
          @post = Post.find(params[:post_id])
          @comment = @post.comments.build(params[:comment].permit(:name, :body))
              #puts "hhhhhhhhhh#{@comment}"
          @comment.user = current_user # I assume you have a variable current_user, or if you are using Devise current_user is already accessible
      
          @comment.save
      
          redirect_to post_path(@post)
        end 
      end
      
      class Ability
        include CanCan::Ability
      
        def initialize(user)
          # if not logged in (Guest)
          unless user
            # cant do anything unless you add more `can` here
          # else if logged in
          else
            case user.role
            when 'admin'
              can :manage, Post
              can :manage, Comment
            when 'normal' # or whatever role you assigned to a normal logged in user
              can :manage, Post, user_id: user.id
              can :manage, Comment, user_id: user.id
            # If you don't have a role name for a normal user, then use the else condition like Rich Peck's answer. Uncomment the following instead, and then comment the `when 'normal' block of code just above
            # else
            #   can :manage, Post, user_id: user.id
            #   can :manage, Comment, user_id: user.id
            end
          end
        end
      end
      
      can [:show, :edit, :update, :destroy], Post, user_id: user.id
      can [:index, :new, :create], Post
      
      class Ability
        include CanCan::Ability
      
        def initialize(user)
            user ||= User.new # guest user (not logged in)
            case user.role
              when "admin"
                 can :manage, :all
              else
                 can :read, Post, :user_id => user.id
            end
        end
      end
      
      class CommentsController < Application
        load_and_authorize_resource
          def index
           @posts = @posts
          end
      end