2016-10-27 166 views
0

無論何時創建新用戶,用戶都會獲得應用的角色。這發生在after_create方法中。這裏是方法:Rails,after_create被調用兩次

def add_user_role 
    self.roles << Role.find_by_role("user") 
end 

但是,用戶獲得兩次角色。在創建之後,這種情況發生:

=> #<ActiveRecord::Associations::CollectionProxy [#<Role id: 21, role: "user", created_at: "2016-10-27 15:13:44", updated_at: "2016-10-27 15:13:44">, #<Role id: 21, role: "user", created_at: "2016-10-27 15:13:44", updated_at: "2016-10-27 15:13:44">]> 
irb(main):002:0> 

如果我註釋掉add命令,沒有一個角色應用於用戶:

def add_user_role 
# self.roles << Role.find_by_role("user") 
end 

創建後:

=> #<ActiveRecord::Associations::CollectionProxy []> 

有沒有人一個想法,爲什麼這是發生?

的after_create方法位於User.rb:

class User < ApplicationRecord 
    after_create :add_user_role 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    has_many :directions 
    has_many :roles, through: :directions 



end 

private 
def add_user_role 
    self.roles << Role.find_by_role("user") 
end 

我有兩個用戶控制器,在這裏,他們是:

用戶控制器爲admin:

class UsersController < ApplicationController 
    before_action :authenticate_user! 
    before_action :current_user_allowed? 



    def edit 
     @user = User.find(params[:id]) 
    end 


    def update 
     @user = User.find(params[:id]) 

     role = params[:role] 
     add_user_role(@user,role) 

     redirect_to root_path 

    end 
end 

private 

def current_user_allowed? 
    current_user.roles.each do |role| 
    if role.role == "superadmin" 
     return 
    end 
    end 
    redirect_to root_path 
end 

def add_user_role(user, role1) 
    user.roles.create(role: role1) 
end 

def user_params 
    params.require(:user).permit(:role) 
end 

控制器from設計:

class Users::RegistrationsController < Devise::RegistrationsController 
# before_action :configure_sign_up_params, only: [:create] 
# before_action :configure_account_update_params, only: [:update] 

    # GET /resource/sign_up 
    # def new 
    # super 
    # end 

    # POST /resource 
    #def create 
    # super 
    #end 

    # GET /resource/edit 
    # def edit 
    # super 
    # end 

    # PUT /resource 
    #def update 
    # super 
    #end 

    # DELETE /resource 
    # def destroy 
    # super 
    # end 

    # GET /resource/cancel 
    # Forces the session data which is usually expired after sign 
    # in to be expired now. This is useful if the user wants to 
    # cancel oauth signing in/up in the middle of the process, 
    # removing all OAuth session data. 
    # def cancel 
    # super 
    # end 

    # protected 

    # If you have extra params to permit, append them to the sanitizer. 
    # def configure_sign_up_params 
    # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) 
    # end 

    # If you have extra params to permit, append them to the sanitizer. 
    # def configure_account_update_params 
    # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) 
    # end 

    # The path used after sign up. 
    # def after_sign_up_path_for(resource) 
    # super(resource) 
    # end 

    # The path used after sign up for inactive accounts. 
    # def after_inactive_sign_up_path_for(resource) 
    # super(resource) 
    # end 


end 
+0

爲什麼你的'add_user_role'在你的'用戶'模型之外的類定義?,我在'end'後面看到它關閉類。 – fanta

+0

@fanta我不知道,我看到,其他人是如何做到的。但是,無論是課內還是課外,我都有同樣的問題。有任何想法嗎? – Metaphysiker

+0

它必須在你的班級內。你介意用'ApplicationRecord'的定義來更新你的文章嗎?那個類是什麼?你可能會有一些東西。 – fanta

回答

0

就在這裏,你有兩件事情做同樣的角色創造。

在users_controller:

def add_user_role(user, role1) 
    user.roles.create(role: role1) 
end 

然後在user.rb:

after_create :add_user_role 

我建議讓控制器進行處理並避免user.rb類中模型的任何修改。

+0

他們是兩種不同的方法。一個接受兩個參數,僅用於更新,另一個不接受任何參數,並在創建後調用。據我所知,創建和更新是兩個不同的操作。我將我的user.rb的名稱更改爲add_default_user_role,但仍然有相同的錯誤。你有什麼進一步的想法? – Metaphysiker

+0

啊,是的,我的道歉,爲了更好的調試,你介意在控制器中寫一個'create'動作並將'after_create'過濾器移到控制器內的一個方法中? – Jeff