我有这两个类:
class Article < ActiveRecord::Base
has_many :article_tags
has_many :tags, through: :article_tags
end
class ArticleTag < ActiveRecord::Base
belongs_to :article
belongs_to :tag
end
class Tag < ActiveRecord::Base
validates :name, format: /\A\p{Alpha}*\z/
end
现在我在文章中添加无效标记:
这有效:
item = Item.new
item.tags << Tag.new(name: '1&+')
item.valid? # Returns false
但这不是
item = Item.find(params[:id])
item.tags << Tag.new(name: '1&+') # Exception here!
原因是 - 如果项目已存在于数据库中 - <<
方法会自动使用save!
保存新标记。
我想要的是具有验证错误的项目,就像在第一种情况下一样。
这可以实现吗?我可以在<<
方法中禁用自动保存吗?
修改
问题似乎是由has_many through
关联引起的。一个简单的has_many
关联不会遇到同样的问题。
调用<<
方法最终会在has_many_through_association.rb
中失败:
def concat(*records)
unless owner.new_record?
records.flatten.each do |record|
raise_on_type_mismatch(record)
record.save! if record.new_record? # Exception here!
end
end
super
end
答案 0 :(得分:1)
我看不到你需要担心的任何事情:)
您最后一行代码将通过。没有问题,因为标记对象不会持久存在 - 它是new
。
该项目在数据库中,但新的“tag”对象不在。它只在内存中。只有在尝试将对象保存到db中时才会触发验证规则。
在控制台中尝试:
> item = Item.find(params[:id])
> item.tags << Tag.new(name: '1&+')
> item.tags[0]
#=> #<Tag:abcd0123> {
# id: nil
# name: '1&+'
# ....
# }
> item.tags[0].save!
#=> ActiveRecord::RecordInvalid: Validation failed