0
我使用CanCanCan和Rails 4,所以每个操作都由load_and_authorize_resource方法授权。一切工作,除了创建行动,它失败,错误:ActiveModel :: ForbiddenAttributesErrorCanCanCan和ForbiddenAttributesError
我认为问题是在CanCan,因为'创建'没有'load_and_authorize_resource'正常工作。
class BuildingsController < ApiController
load_and_authorize_resource
PERMITTED_PARAMS = [:name, :description, deal_info_attributes: [:for_rent, :for_sale, :available_from]]
def create
building = Building.new(create_params.permit(PERMITTED_PARAMS))
building.author_id = current_user.id if user_signed_in?
if building.save
render json: building
else
render json: { errors: building.errors }, status: :bad_request
end
end
end
class ApiController < ActionController::API
def create_params
params.require(controller_name.classify.downcase.to_sym)
end
end
测试:
describe "POST /buildings" do
let(:attrs) { attributes_for(:building) }
let(:deal_info_attributes) { attributes_for(:deal_info) }
it "creates right building" do
api_post "/buildings", building: attrs.merge({ name: "SomeBC", deal_info_attributes: deal_info_attributes })
expect(response).to be_success
end
end
型号:
class Building < ActiveRecord::Base
accepts_nested_attributes_for :deal_info
has_one :deal_info, as: :deal_infoable, dependent: :destroy
# deal_info is polymorphic
end
能力:
class Ability
include CanCan::Ability
def initialize(user, ip=nil)
user ||= User.new # guest user (not logged in)
if user.roles.blank?
can :read, :all
elsif has_local_role?(user) && has_local_ip?(user, ip)
create_permissions(user)
elsif has_local_role?(user) && !has_local_ip?(user, ip)
raise CanCan::AccessDenied
else
create_permissions(user)
end
end
private
def create_permissions(user)
# Permissions example: { 'can' => [{ 'read' => 'all' }, { 'update' => 'room' }], 'cannot' => { 'create' => 'building' } }
user.roles.each do |role|
role.permissions.each do |rights, value|
# Check for the value length is a 'fix' for parsing nested json, e.g. [{},{}]
value.length > 1 ? value.each{ |v| parse_permissions(rights, v, user) } : parse_permissions(rights, value, user)
end
end
end
def parse_permissions(rights, value, user)
value.each do |action, subject|
case rights
when "can"
subject == 'all' ? (can action.to_sym, :all) : (can action.to_sym, subject.classify.constantize)
when "cannot"
subject == 'all' ? (cannot action.to_sym, :all) : (cannot action.to_sym, subject.classify.constantize)
when "only_own"
can action.to_sym, subject.classify.constantize, subject.classify.constantize.where(author_id: user.id) do |subj|
subj.author_id == user.id
end
end
end
end
# has_local_role and has_local_ip not relevant to the problem.
end
这些模型的结构有些奇怪。 你应该建立一个属于建筑物的deal_info,但你正在做相反的事情。或者你可以做相反的事情,做一个建筑belongs_to:deal_info – coorasse 2014-10-03 12:43:42
建筑物有一个交易(offer),我认为没关系:) 无论如何,一切工作到目前为止。 – Evgeny 2014-10-03 12:56:18
你可以发布你的能力模型吗? – Joel 2014-10-03 13:07:00