如何在Rails中定义allow_destroy和:dependent =>:destroy?

JJD*_*JJD 6 dependencies nested ruby-on-rails ruby-on-rails-3

鉴于以下数据库模型,您将如何以及在何处定义模型之间的删除关系?我想出了基本的表关联设置,但是当我想添加依赖项来启用嵌套对象删除时,我就迷失了.

数据库关系模型

这是我创建的关系模型.

class User < ActiveRecord::Base
  has_many :studies
end

class Study < ActiveRecord::Base
  has_many :internships
  belongs_to :student, :class_name => "User", :foreign_key => "user_id"
  belongs_to :subject
  belongs_to :university, :class_name => "Facility", :foreign_key => "facility_id"
  accepts_nested_attributes_for :subject, :university, :locations
end

class Subject < ActiveRecord::Base
  has_many :studies
end

class Internship < ActiveRecord::Base
  belongs_to :study
  belongs_to :company, :class_name => "Facility", :foreign_key => 'facility_id'
  accepts_nested_attributes_for :company, :study
end

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies
  accepts_nested_attributes_for :locations
end

class Location < ActiveRecord::Base
  belongs_to :facility
end
Run Code Online (Sandbox Code Playgroud)

您将在哪里放置:dependent => :destroy:allow_destroy => true启用以下方案?我不想迷惑你.因此,我省略了我的尝试.

实习场景:用户想要删除实习.

  • 如果公司与另一个实习无关,则可以删除其关联公司(设施).
  • 如果是,则可以删除关联公司的位置.
  • 相关研究不会受到影响.

研究方案:用户想要删除研究.

  • 如果没有其他研究涉及该主题,则可以删除其相关主题.
  • 如果没有其他研究提及该大学,可以删除其相关大学(设施).
  • 其相关的实习可以删除.如果没有其他实习机构提及,公司只能被删除.

我完全不确定是否可以在:dependent => :destroy之后has_onehas_many之后添加belongs_to.


编辑:为简化问题,请坚持以下(简化)示例实现.

class Study < ActiveRecord::Base
  belongs_to :subject
  accepts_nested_attributes_for :subject, :allow_destroy => true
end

class Subject < ActiveRecord::Base
  has_many :studies, :dependent => :destroy
end
Run Code Online (Sandbox Code Playgroud)

在我看来,我提供以下链接.

<%= link_to "Destroy", study, :method => :delete, :confirm => "Are you sure?" %>
Run Code Online (Sandbox Code Playgroud)

该路径基于由restful配置给出的命名路由routes.rb.

resources :studies
resources :subjects
Run Code Online (Sandbox Code Playgroud)

当我点击链接时,该研究将被删除 - 主题保持不变.为什么?

leb*_*eze 1

您可以添加:dependent => :destroy到所有三个,但我不确定这是否会给您足够的权力来在确定是否应销毁关联对象之前执行所需的检查。

你有几个选择。

在每个模型上添加 before_destroy 回调,以引发异常或阻止删除发生。

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies

  def before_destroy
    raise SomethingException if internships.any? || ...
    # or
    errors.add(...
  end
end
Run Code Online (Sandbox Code Playgroud)

或者通过覆盖 destroy 来默默地完成

class Facility < ActiveRecord::Base
  has_many :internships
  has_many :locations
  has_many :studies

  def destroy
    return false if internships.any || ...
    super
  end
end
Run Code Online (Sandbox Code Playgroud)

注意:这基本上仅供指导,可能不是覆盖破坏等的正确方法......