2015-03-27 2 views
0

Я использую cancan и devise, я могу обновить удаление и показать, но я не могу создать профиль. почему я не могу создать новый профиль («ActiveModel :: ForbiddenAttributesError»)Может с помощью devise, admin и user

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    if user.is_a?(Admin) 
     can :manage, :all 
    elsif user.is_a?(User) 

     can :read, Profile do |profile| 
     profile.try(:user) == user 
     end 
     can :update, Profile do |profile| 
     profile.try(:user) == user 
     end 
     can :destroy, Profile do |profile| 
     profile.try(:user) == user 
     end 
     can :create, Profile do |profile| 
     profile.try(:user) == user 
    else 
     can :read, :all 
    end 
    end 
end 
+0

Показать пожалуйста контроллер кода. 'ActiveModel :: ForbiddenAttributesError' является сильным параметром. –

ответ

0

Если у вас уже есть load_and_authorize_resource в коде контроллера, вам нужно сделать еще один шаг в дезинфицирующий свои входы через create_params вызова метода в ваш контроллер.

Here's a link to a useful resource

Во-первых: ваша CanCan способность пользователя может быть переписана следующим образом:

can :create, :read, :update, :destroy, Profile, user_id: user.id

Во-вторых: ваши способности администратора должны быть написаны после ваших обычных способностей пользователя, тем самым перекрывая их более успешно:

def initialize(user) 
    # I prefer to alias CRUD actions to keep my ability files more succint 
    alias_action :create, :read, :update, :destroy, to: :crud 

    cannot :manage, :all #Failsafe 

    can :crud, Profile, user_id: user.id 
    ... #additional abilities for user 

    if user.admin? 
    can :manage, :all #Override previous failsafe 

И последнее: если ваш профиль класс belongs_to a Пользователь, вы должны переписать его как таковой. Таким образом, ваш profile_params будет содержать поле user_id.

Если вы должны были следовать, что (правильный) парадигмы, #create действие вашего ProfilesController была бы выглядеть примерно так:

class ProfilesController < ApplicationController 
    load_and_authorize_resource 

    def create 
    @profile = Profile.new(profile_params) 
     if @profile.save 
     ... 
     else 
     ... 
     end 
    end 

    private 
    def profile_params 
     params.require(:profile).permit(:user_id, ...) 
    end 
end 
+0

Можете ли вы помочь мне больше, я больше не знаю канкан. Как видите, у меня есть профиль, вложенный под пользователем, и администратор должен контролировать все. Мне нужно написать before_action в контроллере профиля –

+0

Обновлен мой ответ, чтобы дать вам возможное (легкое) обходное решение. –

+0

не сработал нужно выяснить это –

0
class ProfilesController < ApplicationController 
    before_action :set_profile, only: [:show, :edit, :update, :destroy] 
    load_and_authorize_resource 


    # GET /profiles 
    # GET /profiles.json 
    def index 
    user = User.find(params[:user_id]) 
    @profiles = user.profiles 

    respond_to do |format| 
     format.html 
     format.xml {render :xml => @profiles} 
    end 
    end 

    # GET /profiles/1 
    # GET /profiles/1.json 
    def show 
    user = User.find(params[:user_id]) 
    @profiles = user.profiles.find(params[:id]) 

    respond_to do |format| 
     format.html 
     format.xml {render :xml => @profile} 
     end 
    end 

    # GET /profiles/new 
    def new 
    user = User.find(params[:user_id]) 
    @profile = user.profiles.build 

    respond_to do |format| 
     format.html 
     format.xml {render :xml => @profile} 
     end 
    end 

    # GET /profiles/1/edit 
    def edit 
    user = User.find(params[:user_id]) 
    @profiles = user.profiles.find(params[:id]) 
    end 

    # POST /profiles 
    # POST /profiles.json 
    def create 
    user = User.find(params[:user_id]) 
    @profile = user.profiles.create(profile_params) 

    respond_to do |format| 
     if @profile.save 
     format.html { redirect_to user_profiles_url, notice: 'Profile was successfully created.' } 
     format.json { render action: 'show', status: :created, location: @profile } 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @profile.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /profiles/1 
    # PATCH/PUT /profiles/1.json 
    def update 
    user = User.find(params[:user_id]) 
    @profiles = user.profiles.find(params[:id]) 

    respond_to do |format| 
     if @profile.update(profile_params) 
     format.html { redirect_to user_profile_url, notice: 'Profile was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit' } 
     format.json { render json: @profile.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /profiles/1 
    # DELETE /profiles/1.json 
    def destroy 
    user = User.find(params[:user_id]) 
    @profiles = user.profiles.find(params[:id]) 

    @profile.destroy 
    respond_to do |format| 
     format.html { redirect_to job_hunters_path } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_profile 
     @profile = Profile.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def profile_params 
     params.require(:profile).permit(:full_name, :phone_number, :email, :position, :years_of_experiance, :cover_letter, :resume, :reference) 
    end 
end 
Смежные вопросы