2009-10-12 6 views
0

계정 모델 (has_many : users)과 사용자 모델 (belongs_to : account, : dependent => : destroy)의 두 모델이 문제가 있습니다. 내가 삭제되는 마스터 사용자를 보호하기 위해 노력하고있어종속성 => : destroy 및 before_filter

def protect_master_user 
    unless User.find_all_by_account_id_and_is_master(self.account_id, true).count > 1 
    false 
    end 
end 

:

내 사용자 모델은 다음있다. 상위 (계정)가 삭제 된 경우이를 어떻게 무시할 수 있습니까? 나는 시도 : 종속 => : 파괴 및 : 아무 소용이 삭제하십시오.

EDIT : 고정 코드.

답변

1

has_many : users, : dependent => : delete_all 또는 계정의 추가 사용자 정의 콜백이 있습니다. : delete_all 메소드는 더 간단하지만 권고하지는 않는다. 왜냐하면 다른 콜백이 사용자 레코드에서 일어나지 않기 때문이다.

올바른 해결책은 사용자의 콜백과 함께 작동하는 Account의 custom before_destroy 콜백입니다.

class Account < ActiveRecord::Base 
    has_many :users 

    before_destroy :destroy_users 
    protected 
    def destroy_users 
     users.each do |user| 
     u.account_id = nil 
     u.destroy 
     end 
    end 

end 

class User < ActiveRecord::Base 
    belongs_to :account 

    before_destroy :protect_master_user 

    protected 
    def protect_master_user 
     unless account_id.nil? ||! master || 
     User.find_all_by_account_id_and_master(self.account_id, true).count > 1 
     errors.add_to_base "Cannot remove master user." 
     return false 
     end 
    end 
end 

account.id가 nil 인 경우를 제외하고는 단락 회로를 사용하고 destroy는 계속됩니다. 사용자가 마스터 사용자가 아닌 경우에도 마찬가지입니다. 파괴되는 객체가 마스터 사용자가 아닌 경우에도 둘 이상의 마스터 사용자가 있는지 확인해야하는 이유는 무엇입니까?

다시 말해서 삭제 대신 삭제를 사용할 수 있습니다. 그러나 당신이 가지고 있거나 미래에있을 모든 * _destroy 콜백을 건너 뜁니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 이것은 저에게 맞지 않습니다. 당신이 제안한 것은 의미가 있지만, 사용자 파괴가 제일 먼저한다고 생각합니다. 다른 아이디어? –

+0

이상한. 나는 그것이 어제 일하고 있다고 생각했다. 사용자 정의 콜백을 사용하도록 업데이트했으며 왜 : depend => : delete_all이 좋지 않은지 설명했습니다. – EmFi

+0

감사합니다. 동일한 솔루션을 제안했지만 계정 모델에서 사용자를 삭제하는 것이 확실한 것인지 잘 모르겠습니다. 다시 한번 감사드립니다. –

0

나는 아주 똑같은 질문과 수수께끼를 최근에 가지고 있었고이 문제를 다루는 가장 좋은 방법은 컨트롤러에서 처리하는 것이었다. 사용자가 시스템 그것을하고있다 :

class UsersController < ApplicationController 
    def destroy 
     user = current_account.users.find(params[:id].to_i) 
     if allow_removal_of_user?(user) && user.destroy 
     redirect_to users_path, :notice => "User sucessfully deleted" 
     else 
     flash[:error] = user.errors.empty? ? "Error" : user.errors.full_messages.to_sentence 
     render :edit 
     end 
    end 

    private 
    def allow_removal_of_user?(user) 
     if user == current_user 
     errors.add(:user_removal, "Can't delete yourself") 
     false 
     elsif user.only_user? || (user.master_users_for_account.count == 1 && user.master_role?) 
     errors.add(:user_removal, "Can't delete last Master user") 
     false 
     else 
     true 
     end 
    end 
    end 

희망이 누군가를 돕는다!