我有两个模型之间的多对多关系如下:
#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
答案 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