遇到问题:依赖=> :destroy和before_filter

时间:2009-10-12 06:28:07

标签: ruby-on-rails

两个模型,一个帐户模型(has_many:用户)和一个用户模型(belongs_to:account,:dependent =>:destroy)。

我的用户模型具有以下内容:

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

我正在尝试保护主用户不被删除。如果删除父(帐户),我该如何覆盖它?我试过了:dependent => :破坏和:删除无济于事。

编辑:固定代码。

2 个答案:

答案 0 :(得分:1)

有两种方法可以做到这一点:has_many:users,:dependent => :delete_all,或在Accounts中使用其他自定义回调。 :delete_all方法更简单,但不建议,因为这意味着您的其他回调都不会发生在用户记录上。

正确的解决方案是在Account中自定义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为零,我们将短路除去,并且销毁继续。如果用户不是主用户,则同样如此。如果被销毁的对象不是主用户,为什么我们需要检查是否有多个主用户呢?

同样,删除可用于代替销毁。但是它会跳过你将来或将来会有的任何* _destroy回调。

答案 1 :(得分: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

希望这有助于某人!