如何确保rails ActiveRecord模型在给定状态下总是有多个?

时间:2022-06-21 20:14:55

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:

我建议如下:

  1. Add a column active to the templates. Add uniqueness validation to it within the site scope.
  2. 向模板添加活动列。在站点范围内为其添加唯一性验证。
  3. Add a custom validation to site, which will check if there is an active template.
  4. 向站点添加自定义验证,该验证将检查是否存在活动模板。

#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:

我建议如下:

  1. Add a column active to the templates. Add uniqueness validation to it within the site scope.
  2. 向模板添加活动列。在站点范围内为其添加唯一性验证。
  3. Add a custom validation to site, which will check if there is an active template.
  4. 向站点添加自定义验证,该验证将检查是否存在活动模板。

#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。