I have two ActiveRecord models; Site
and Template
.
我有两个ActiveRecord模型;网站和模板。
A site has_many
templates and must always have one active template, i.e. a site should not be without an active template, and should never be more than one template marked as active at one time.
一个站点has_many模板,并且必须始终有一个活动模板,即一个站点不应该没有活动模板,并且永远不应该是一次标记为活动的多个模板。
How can I enforce this relationship within ActiveRecord within a Rails 5 app?
如何在Rails 5应用程序中的ActiveRecord中强制执行此关系?
3 个解决方案
#1
1
I would add an active
boolean column to the Template
model.
我会在Template模型中添加一个活动的布尔列。
To ensure that there is at least one active template add a custom validation to your Template
model:
要确保至少有一个活动模板,请为模板模型添加自定义验证:
validate :at_least_one_active
def at_least_one_active
return if active || site.templates.where(active: true).exist?
errors.add(:active, 'at least one must be active')
end
To ensure that is only one active template I would use an after_save
callback in the Template
model:
为了确保只有一个活动模板,我将在Template模型中使用after_save回调:
after_save :only_on_active
def only_one_active
return unless active
site.templates.where(active: true).where.not(id: id).update_all(active: false)
end
To ensure that you cannot delete the only active
template add a before_destroy
callback:
要确保您无法删除唯一的活动模板,请添加before_destroy回调:
before_destroy :cannot_destroy_active_template
def cannot_destroy_active_template
raise :abort if active
end
#2
0
I suggest the following:
我建议如下:
- Add a column
active
to the templates. Add uniqueness validation to it within the site scope. - 向模板添加活动列。在站点范围内为其添加唯一性验证。
- Add a custom validation to site, which will check if there is an active template.
- 向站点添加自定义验证,该验证将检查是否存在活动模板。
#3
0
You should add
你应该添加
class Site < ActiveRecord::Base
belongs_to :active_template
validate :active_template, presence: true
end
And add an active_template_id to your model's table. Also you can add has_one :active_site within your Template model, but nil should be allowed.
并将active_template_id添加到模型的表中。您还可以在模板模型中添加has_one:active_site,但应允许nil。
#1
1
I would add an active
boolean column to the Template
model.
我会在Template模型中添加一个活动的布尔列。
To ensure that there is at least one active template add a custom validation to your Template
model:
要确保至少有一个活动模板,请为模板模型添加自定义验证:
validate :at_least_one_active
def at_least_one_active
return if active || site.templates.where(active: true).exist?
errors.add(:active, 'at least one must be active')
end
To ensure that is only one active template I would use an after_save
callback in the Template
model:
为了确保只有一个活动模板,我将在Template模型中使用after_save回调:
after_save :only_on_active
def only_one_active
return unless active
site.templates.where(active: true).where.not(id: id).update_all(active: false)
end
To ensure that you cannot delete the only active
template add a before_destroy
callback:
要确保您无法删除唯一的活动模板,请添加before_destroy回调:
before_destroy :cannot_destroy_active_template
def cannot_destroy_active_template
raise :abort if active
end
#2
0
I suggest the following:
我建议如下:
- Add a column
active
to the templates. Add uniqueness validation to it within the site scope. - 向模板添加活动列。在站点范围内为其添加唯一性验证。
- Add a custom validation to site, which will check if there is an active template.
- 向站点添加自定义验证,该验证将检查是否存在活动模板。
#3
0
You should add
你应该添加
class Site < ActiveRecord::Base
belongs_to :active_template
validate :active_template, presence: true
end
And add an active_template_id to your model's table. Also you can add has_one :active_site within your Template model, but nil should be allowed.
并将active_template_id添加到模型的表中。您还可以在模板模型中添加has_one:active_site,但应允许nil。