如果关联存在,如何禁止删除

时间:2013-06-29 13:38:59

标签: ruby-on-rails-3 activerecord dependencies model-associations

我有两个模型之间的多对多关系如下:

#users.rb
has_many :users_to_roles
has_many :roles, through: :users_to_roles

#users_to_roles.rb
belongs_to :user
belongs_to :role

#roles.rb
has_many :users_to_roles
has_many :users, through: :users_to_roles

如果有“处于此角色”的用户,我想禁用删除角色。 Here我找到了两个应该做的工作:

  

:restrict_with_exception会导致引发异常   任何相关记录:restrict_with_error会导致错误   如果有任何关联对象,则添加到所有者

但是没有关于它的语法和它应该如何工作的例子。你能帮忙使这个有效吗?

#roles.rb
has_many :users_to_roles
has_many :users, through: :users_to_roles, dependent: restrict_with_exception

4 个答案:

答案 0 :(得分:2)

使用Callbacks可以轻松完成此类操作。在我的例子中,我在我的模型中添加了以下方法:

# callbacks
before_destroy :check_for_users_in_this_role

def check_for_users_in_this_role
  status = true
  if self.security_users.count > 0
    self.errors[:deletion_status] = 'Cannot delete security role with active users in it.'
    status = false
  else
    self.errors[:deletion_status] = 'OK.'
  end
  status
end

答案 1 :(得分:2)

或者,您可以在控制器中挽救异常。在这个例子中,联系人可能有兴趣,即

  class Interest < ActiveRecord::Base
    belongs_to :contact
  end

  class Contact < ActiveRecord::Base
    has_many :interests, :dependent => :restrict
   end

然后在控制器中:

def destroy
    @contact = Contact.find(params[:id])
    begin
        @contact.destroy
    rescue
        flash[:msg] = "Can't delete - owns interest"
    end

   respond_to do |format|
      format.html { redirect_to(:back) }
      format.xml  { head :ok }
    end
end

Flash消息将显示在呼叫页面中。

答案 2 :(得分:0)

正确的 rails方式是执行以下操作:

users.rb的:

has_many :users_to_roles, dependant: :destroy # don't keep the join table entry if the user is gone
has_many :roles, through: :users_to_roles

确保您的联接没有冗余条目(其中任一列为null或孤立)。

users_to_roles.rb:

belongs_to :user
belongs_to :role

# add validations presence of both user and role
# in both model and database.

Bonus,来自rails 4.2,您可以在referential integrity的迁移中添加forigen_key: true

现在你的角色(我假设你单独命名你的模型并在问题中输入错误),你添加这个:

role.rb:

has_many :users_to_roles, dependant: :restrict_with_error
has_many :users, through: :users_to_roles

答案 3 :(得分:0)

我用我这样的课程做到了:

应用/模型/ guest_chat_token.rb

class GuestChatToken < ApplicationRecord

  has_many :chat_messages, as: :sendable, dependent: :restrict_with_exception

end

应用/控制器/管理/ application_controller.rb

class Admin::ApplicationController < ApplicationController
....
    rescue_from ActiveRecord::DeleteRestrictionError do |exception|
            redirect_to :back, notice:
            "Be aware: #{exception.message}."
    end
end