如何定义allow_destroy和:dependent => : 在 Rails 中销毁?
给定以下数据库模型,您将如何以及在何处定义模型之间的删除关系?我弄清楚了基本的表关联设置,但是当我想添加依赖项以启用删除嵌套对象时,我迷失了。
这是我创建的关系模型。
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
你会把 :dependent => 放在哪里:destroy
和 :allow_destroy => true
启用以下场景?我不想让你感到困惑。因此,我省略了我的尝试。
实习场景:用户想要删除实习。
- 如果该公司与其他实习无关,则可以删除其关联公司(设施)。
- 如果是这样,则可以删除关联公司的位置。
- 相关研究不会受到影响。
研究场景:用户想要删除一项研究。
- 如果没有其他研究引用该主题,则可以删除其相关主题。
- 如果没有其他研究提及该大学,则可以删除其关联大学(设施)。
- 其关联的实习可以删除。只有在没有其他实习涉及该公司的情况下才能删除该公司。
我完全不确定是否可以添加 :dependent =>; :destroy
仅在 has_one
和 has_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
在我看来,我提供以下链接。
<%= link_to "Destroy", study, :method => :delete, :confirm => "Are you sure?" %>
该路径基于 routes.rb
中的静态配置给出的命名路由。
resources :studies
resources :subjects
当我点击链接时,该研究将被删除 - 受试者保持不变。为什么?
Given the following database model, how and where would you define the deletion relationships between the models? I figured out the basic table association setup but when I want to add dependencies to enable the deletion of nested objects I get lost.
Here is the relationship model I created.
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
Where would you put :dependent => :destroy
and :allow_destroy => true
to enable the following scenarios? I do not want to confuse you. Therefore, I leave out my tryings.
Internship scenario: A user wants to delete an internship.
- Its associated company (facility) can be deleted if the company is not related to another internship.
- If so, the locations of the associated company can be deleted.
- The related study will not be affected.
Study scenario: A user wants to delete a study.
- Its associated subject can be deleted if no other study refers to this subject.
- Its associated university (facility) can be deleted if no other study refers to this university.
- Its associated internships can be deleted. The company can only be deleted if no other internship refers to it.
I am totally unsure whether I can add :dependent => :destroy
only after has_one
and has_many
or also after belongs_to
.
Edit: To simplify the problem please stick to the following (reduced) example implementation.
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
In my view I provide the following link.
<%= link_to "Destroy", study, :method => :delete, :confirm => "Are you sure?" %>
The path is based on the named routes given by a restful configuration in routes.rb
.
resources :studies
resources :subjects
The study will be deleted when I click the link - the subjects stays untouched. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你们的关系在这里是错误的......
应在
has_many
所属模型的has_many
模型上声明accepts_nested_attributes_for
。此外,在您的示例中,销毁主题将对许多研究
强制执行dependent_destroy
,而不是相反。I think your relations are the wrong way around here...
The
accepts_nested_attributes_for
should be declared on the model thathas_many
for the model that ithas_many
of. Also, in your example, destroying the subject would enforcedependent_destroy
on the manystudies
, not the other way around.您可以添加
:dependent =>; :destroy
对所有三个,但我不确定这是否会给您足够的权力来在确定是否应销毁关联对象之前执行所需的检查。你有几个选择。
在每个模型上添加 before_destroy 回调,以引发异常或阻止删除发生。
或者通过重写 destroy 来默默地执行此操作
注意:这基本上仅用于指导,可能不是重写 destroy 等的正确方法...
You can add
:dependent => :destroy
to all three but I'm not sure if that'll give you enough power to do the checks required before determining whether an associated object should be destroyed.You have a few options.
Add a before_destroy callback on each model that raises an exception or stops the delete from occurring.
or do it silently by overriding destroy
Note: this is basically meant for guidance only and may not be the correct way of overriding destroy etc...