CanCan、Devise、Rails 和 Backbone.js,存在 :update 问题

发布于 2024-11-18 21:39:40 字数 1988 浏览 2 评论 0原文

我使用 Devise 和 CanCan 创建一个 Backbone.js 前端,并使用 Rails 3.0.7 作为后端。

一旦我将 load_and_authorize_resource 添加到我的控制器,它就不再允许我执行更新,并且我没有从服务器得到任何响应。如果我从控制器中删除 load_and_authorize_resource,则一切正常。

来自我的控制台的信息:

于 2011 年 7 月 7 日星期四 15:06:41 -0700 开始对 127.0.0.1 进行 PUT“/pos/13”

由 PosController#update 作为 JSON 处理

参数:{"confirmed"=>nil, "paid"=>nil, "needed"=>Thu, 30 Jun 2011, "amount"=>16, "id"=>"13 ", "已批准"=>1, "user_id"=>1, "vendor_id"=>5}

用户负载(0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1

Po 负载(0.1ms) SELECT "pos".* FROM "pos" WHERE "pos"."id" = 13 LIMIT 1

角色加载 (0.1ms) SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles".id = "roles_users".role_id WHERE "roles"."name" = 'Admin' AND ( “roles_users”.user_id = NULL ) LIMIT 1

最后一个查询的结尾: "roles_users".user_id = NULL 永远不会返回任何结果,并且不会让我更新资源。我可以做什么来解决这个问题?

其他信息:

PosController#update 如下所示:

def update
  @po = Po.find(params[:id])
  @po.update_attributes! params
  respond_with @po
end

我正在使用角色来管理能力。我的ability.rb 看起来像:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.role? :admin
      can :manage, :all
    end
  end
end

User.rb 包含:

def role?(role)
  return !!self.roles.find_by_name(role.to_s.camelize)
end

角色是从UsersHaveAndBelongToManyRoles 迁移中获取的:

class UsersHaveAndBelongToManyRoles < ActiveRecord::Migration
  def self.up
    create_table :roles_users, :id => false do |t|
     t.references :role, :user
    end
  end

  def self.down
    drop_table :roles_users
  end
end

我目前只有一个用户,并已为该用户授予角色admin。我已经能够通过使用条件来仔细检查这一点,以不在 PosController#index 中传递任何 @pos,除非 current_user.role? :管理员。

I'm using Devise and CanCan to create a backbone.js front-end and Rails 3.0.7 for backend.

As soon as I add load_and_authorize_resource to my controller it no longer lets me perform an update and I get no response from the server. If I remove load_and_authorize_resource from my controller, everything works well.

Information from my console:

Started PUT "/pos/13" for 127.0.0.1 at Thu Jul 07 15:06:41 -0700 2011

Processing by PosController#update as JSON

Parameters: {"confirmed"=>nil, "paid"=>nil, "needed"=>Thu, 30 Jun 2011, "amount"=>16, "id"=>"13", "approved"=>1, "user_id"=>1, "vendor_id"=>5}

User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1

Po Load (0.1ms) SELECT "pos".* FROM "pos" WHERE "pos"."id" = 13 LIMIT 1

Role Load (0.1ms) SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles".id = "roles_users".role_id WHERE "roles"."name" = 'Admin' AND ("roles_users".user_id = NULL ) LIMIT 1

The end of the last query: "roles_users".user_id = NULL is never going to return any results and will then not let me update the resource. What could I do to fix this?

Other information:

PosController#update looks like this:

def update
  @po = Po.find(params[:id])
  @po.update_attributes! params
  respond_with @po
end

I'm using roles to manage abilities. My ability.rb looks like:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.role? :admin
      can :manage, :all
    end
  end
end

User.rb contains:

def role?(role)
  return !!self.roles.find_by_name(role.to_s.camelize)
end

Roles are obtained from the UsersHaveAndBelongToManyRoles migration:

class UsersHaveAndBelongToManyRoles < ActiveRecord::Migration
  def self.up
    create_table :roles_users, :id => false do |t|
     t.references :role, :user
    end
  end

  def self.down
    drop_table :roles_users
  end
end

I currently only have one user, and have given this user the role admin. I've been able to double check this by using a conditional to not pass any @pos in PosController#index unless current_user.role? :admin.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浪漫之都 2024-11-25 21:39:40

这可能是 Devise 在 AJAX 请求上丢失身份验证的问题,请查看此问题了解详细信息。

看起来传递给Ability的current_user为零。尝试删除 load_and_authorize_resource 并确保在操作中正确设置 current_user。

如果这不是问题,请首先确定 user.role? :admin 为该用户返回 true。接下来,尝试 Ability.new(user).can?(:update, Po.find(...)),请参阅 调试能力 了解详细信息。

我不明白的是为什么它返回一个空的 JSON 响应。 CanCan 从不直接处理响应,它只是在授权失败时引发异常。您是否在 ApplicationController 中使用 rescue_from 捕获了这一点?如果是这样,请尝试删除它以确保授权实际上失败并且没有其他任何东西正在处理 JSON 响应。

This may be a problem with Devise losing authentication on AJAX requests, check out this issue for details.

It looks like current_user that is passed to Ability is nil. Try removing load_and_authorize_resource and ensure that current_user is set correctly in the action.

If that is not the problem, first make sure user.role? :admin is returning true for that user. Next, try Ability.new(user).can?(:update, Po.find(...)), see Debugging Abilities for details.

What I don't understand is why it returns an empty JSON response. CanCan never handles a response directly, it just raises an exception when authorization fails. Are you catching this with rescue_from in your ApplicationController? If so, try removing that to ensure Authorization is actually failing and nothing else is handling the JSON response.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文