0

我有这两个类:

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
4

1 回答 1

1

我看不到您需要担心的任何事情:)

您的最后一行代码将通过。没有问题,因为标签对象不是持久化的 - 它是new.

该项目在数据库中,但新的“标签”对象不在。它只存在于记忆中。只有当您尝试将对象保存到数据库中时才会触发验证规则。

在控制台中试试这个:

> 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
于 2013-05-26T14:36:49.340 回答