CanCan、Devise、Rails 和 Backbone.js,存在 :update 问题
我使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这可能是 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, tryAbility.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.