如何防止在Rails中的关联表中保存无效ID?

时间:2018-02-06 16:36:05

标签: ruby-on-rails validation many-to-many

我的Rails应用中有两个表:CategoryService。我还在它们之间创建了一个关联表CategoriesService,除了验证CategoriesService表上的id之外,一切正常 - 我只是注意到我能够创建一个与不存在的记录的关联。我想知道如何正确地修复它 - 我怀疑Rails应该让我们创建一些数据库级别的验证,这可能更快更干净。我这样定义了我的模型:

class Category < ApplicationRecord
  has_and_belongs_to_many :services
end

class Service < ApplicationRecord
  has_and_belongs_to_many :categories
end

class CategoriesService < ApplicationRecord
end

我当时认为创建has_and_belongs_to_many关系会确保这种验证本身,但我可以看到我错了。我该怎么解决这个问题?

1 个答案:

答案 0 :(得分:1)

来自Rails style guide

  

首选has_many :throughhas_and_belongs_to_many。使用has_many :through可以在连接模型上添加其他属性和验证。

在你的情况下:

class Category < ApplicationRecord
  has_many :categories_services
  has_many :services, through: :categories_services
end

class Service < ApplicationRecord
  has_many :categories_services
  has_many :categories, through: :categories_services
end

class CategoriesService < ApplicationRecord
  belongs_to :category
  belongs_to :service

  # if not using Rails 5:
  validates :category, presence: true
  validates :service, presence: true
  # if using Rails 5, a `belongs_to` will auto-validate the presence
end

使用连接模型(而不是has_and_belongs_to_many),您可以更好地控制多对多关系:

  • 你(可以)在联接表上有created_atupdated_at字段,由Rails自动管理
  • 您可以改进联接模型,例如,使用列position,然后您可以提供对特定services的{​​{1}}进行排序的功能,{{1 } boolean column等。

此外,您可以(我建议您这样做)通过在数据库中添加一些约束来强制执行此验证:

category