我希望能够与关联的多对多实体一起创建和编辑模型。相关对象应通过具有附加字段和完整性验证(例如唯一性或存在性)的模型连接起来。我想用 Rails 提供的标准验证机制检查完整性。
一个例子是 a Post
(就像 Stackoverflow 上的这里),至少有一个Tag
并且不超过 3 Tags
。Tag
不能多次分配给 single Post
。此外,标签将被排序(priority
在连接表中)。
如果违反任何约束,模型应该使用自定义验证器validates
并添加错误消息。Post#errors
在编辑时,如果任何验证失败(例如删除帖子标题或添加太多标签),将不会保存模型及其与Tag
( ) 的关系。TagAssignment
示例模型:
class Post < ActiveRecord::Base
has_many :tag_assignments
has_many :tags, :through => :tag_assignments
validates :title,
presence: true
validates :content,
presence: true
validates :number_of_tags
def number_of_tags
valid = self.tags.count.in? 1..3
errors.add('error: 1 <= tag.size <= 3') unless valid
valid
end
end
class Tag < ActiveRecord::Base
has_many :tag_assignments
has_many :posts, through: :tag_assignment
validates :name,
presence: true
end
class TagAssignment < ActiveRecord::Base
belongs_to :user
belongs_to :tag
validates :tag_id,
uniqueness: {scope: :post_id}
validates :priority,
presence: true,
uniqueness: {scope: :tag_id}
end
示例用法:
post = Post.build(title: 'title', content: 'content')
post.save # false
post.errors # contains message: 'error: 1 <= tag.size <= 3'
post.tagger << Tag.first
post.save # true
post_id = post.id
post = Post.find(post_id)
post.tagger << Tag.all[5..10]
post.save # false
# but tag_assignments were already created
# and old TagAssignments were not destroyed
(在示例中,我假设这是一种使用 settagger
构建的方法)TagAssignments
priority
管理 habtm 关系并从内置验证系统中受益的最佳设计模式是什么?