【问题标题】:Devise and cancan gems: has_many association设计和康康宝石:has_many 关联
【发布时间】:2012-07-08 15:04:27
【问题描述】:

我使用 devisecancan gems 并且有简单的模型关联:user has_many subscriptions, subscription belongs_to :user。有关注SubscriptionsController:

class SubscriptionsController < ApplicationController

  load_and_authorize_resource :user
  load_and_authorize_resource :subscription, through: :user

  before_filter :authenticate_user!

  def index
    @subscriptions = @user.subscriptions.paginate(:page => params[:page]).order(:created_at)
  end

  #other actions
end

还有CancanAbility.rb

class Ability
  include CanCan::Ability

  def initialize(user)

    user ||=User.new

    can [:read], [Edition, Kind]

    if user.admin?
      can :manage, :all
    elsif user.id
      can [:read, :create, :destroy, :pay], Subscription, user_id: user.id
      can [:delete_from_cart, :add_to_cart, :cart], User, id: user.id
    end

  end

end

问题是我不能以用户身份使用subscriptions 操作,但可以以管理员身份使用。并且对UsersController 没有任何问题。当我从SubscriptionsController 中删除以下行时:

  load_and_authorize_resource :user
  load_and_authorize_resource :subscription, through: :user

  before_filter :authenticate_user!

完全没有问题。所以这些行或Ability.rb 中的问题。有什么建议吗?

更新:有趣的是,如果我将 can? :index, Subscription 之类的东西添加到 html 模板中,它会显示 true。如果添加像can? :index, Subscription.first(另一个用户的订阅)这样的东西,它会显示false。看起来Cancan 工作正常。但是有什么问题呢?..

更新:如果更改SubscriptionsControlle 喜欢:

class SubscriptionsController < ApplicationController

  #load_and_authorize_resource :user
  #load_and_authorize_resource :subscription, through: :user

  before_filter :authenticate_user!

  def show
    @user = User.find params[:user_id] #line 1
    @subscription = @user.subscriptions.find params[:id] #line 2
    @container_items = @subscription.container_items.paginate(:page => params[:page])
    authorize! :show, @subscription #line 4
  end

  #some actions
end

它可以完美运行,并在需要时防止未经授权的用户访问。 第 1 行、第 2 行和第 4 行是否不等于已注释?..

更新:在routes.rb 中有以下内容:

resources :users, except: [:show] do
    member do
      get 'cart'
      delete 'delete_from_cart' => 'users#delete_from_cart'
      post 'add_to_cart' => 'users#add_to_cart'
    end
    resources :subscriptions do
      member do
        post 'pay'
      end
    end
  end

更新:下一个解决方案可防止未经授权访问除index 之外的所有订阅操作:

class SubscriptionsController < ApplicationController

  load_resource :user
  load_resource :subscription, through: :user
  authorize_resource through: :current_user

  before_filter :authenticate_user!

  #actions
end

那么阻止访问index 操作的最佳方法是什么?

仅找到以下解决方案:

  before_filter :authorize_index, only: [:index]

  def authorize_index
    raise CanCan::AccessDenied unless params[:user_id] == current_user.id.to_s
  end

【问题讨论】:

    标签: ruby-on-rails devise authorization cancan has-many


    【解决方案1】:

    应该是

    load_and_authorize_resource :subscription
    

    或者只是

    load_and_authorize_resource
    

    在你的情况下,当你想要嵌套资源时,那么

    load_and_authorize_resource :through => :current_user
    

    https://github.com/ryanb/cancan/wiki/Nested-Resources

    【讨论】:

    • 所以我可以在那里看到:class TasksController &lt; ApplicationController load_and_authorize_resource :project load_and_authorize_resource :task, :through =&gt; :project end。又有什么区别?
    • 您希望“load_and_authorize_resource :user”如何工作?它应该用什么授权用户实例?
    • 我的routes.rb有关注:resources :users, except: [:show] do resources :subscriptions do member do post 'pay' end end end
    • 表示网址中有:user_id
    • 是的,但我再说一遍 - 用什么授权?您可能需要改为: load_resource :user
    猜你喜欢
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2012-06-06
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多