多くの sを持つEntry
モデルがあります。s は、仮想属性を介してフォームのテキスト ボックスに入力することでエントリに追加されます。モデルで検証する前に、tag_names 文字列はを使用して実際のオブジェクトに変換されます。このモデルには、タグ名が関連付けを介して実行される正規表現と一致することを確認するための検証もあります。Tag
Tag
tag_names
Entry
Tag
find_or_create_by_name
Tag
私のエントリーモデルは次のようになります。
class Entry < ActiveRecord::Base
has_many :entry_tags
has_many :tags, :through => :entry_tags
before_validation :update_tags
attr_writer :tag_names
private
def update_tags
if @tag_names
self.tags = @tag_names.split(",").uniq.map do |name|
Tag.find_or_create_by_name(name.strip)
end
end
end
end
新しいEntry
オブジェクトを作成してタグを割り当てると、すべてが正しく機能します。Tag
の 1 つに検証エラーがある場合、タグは保存されず、エラー メッセージが返されます。ただし、メッセージを返す代わりに、既存の Entry オブジェクトを無効なタグで更新しようとすると、self.tags=
(上記の) 呼び出しでupdate_tags
検証エラー メッセージとともに例外がスローされます。find_or_create_by_name
を呼び出す代わりに実際に新しいオブジェクトを返すように上書きしてもcreate
、同じ結果が得られます。
オブジェクトが既に存在する場合、メインレコードが保存される前に、呼び出しが実際にオブジェクトを保存しているように思えます(そしてドキュメントが裏付けているようです) 。この保存が発生しないようにするために、または例外が発生して保存が false を返すのを防ぐためにできることはありますか?tags=
Tag
Entry