0

私はこれらの2つのクラスを持っています:

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

アイテムはデータベースにありますが、新しい「タグ」オブジェクトはありません。記憶にあるだけです。検証ルールは、オブジェクトを 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
于 2013-05-26T14:36:49.340 に答える