【问题标题】:How to forbid deletion if association present如果存在关联,如何禁止删除
【发布时间】:2013-06-29 13:38:58
【问题描述】:

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

#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 会导致错误 如果有任何关联对象,则添加到所有者

但是没有关于 this 的语法以及它应该如何工作的示例。

您能否帮助使其有效:

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

【问题讨论】:

  • 您在这方面的看法如何?如果您不希望用户删除某些内容,您可以使用 Ruby 在指定条件下禁用删除按钮/链接。我认为这比允许删除操作开始,然后在不满足条件时生成错误要好。
  • @mbratch 我已经这样做了。你觉得这就够了吗?我是 Rails 新手,但感觉不到这种良好的保护 - 毕竟如果有人成功删除角色,应用程序将停止正常工作。
  • 啊,这是个好问题。我想用户可以构建一条路线,当您不打算这样做时,该路线将被删除。您可以执行此处描述的操作:stackoverflow.com/questions/123078/…

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


【解决方案1】:

使用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

【讨论】:

    【解决方案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
    

    来电页面会显示快讯。

    【讨论】:

      【解决方案3】:

      正确的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
      

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

      users_to_roles.rb:

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

      奖励,从 Rails 4.2 开始,您可以在迁移中为 referential integrity 添加 forigen_key: true

      现在担任您的角色(我假设您单独命名您的模型并在问题中打错字),您添加以下内容:

      角色.rb:

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

      【讨论】:

        【解决方案4】:

        我的课程是这样的:

        app/models/guest_chat_token.rb

        class GuestChatToken < ApplicationRecord
        
          has_many :chat_messages, as: :sendable, dependent: :restrict_with_exception
        
        end
        

        app/controllers/admin/application_controller.rb

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多