1

Rails3はvalidates_associatedデフォルトで常にすべてのモデルに対して実行されますか?

このような簡単なセットアップで

class Post < ActiveRecord::Base
    has_many :comments
end

class Comment < ActiveRecord::Base
    belongs_to :post

    def validate
        errors.add_to_base("its always invalid")
    end
end

コメントが無効なため、コメントが添付された新しい投稿は失敗します。

a = Post.new
a.comments << Comment.new
a.errors
    => {:comments=>["is invalid"]}

validates_associated常に実行されている場合、なぜそこにあるのですか(変更するため:messageですか?)、どうすればオフにできますか?試しvalidates_associated :comments, :unless => proc{true}ましたが、何もしません。

モデルを保存したいだけです。それぞれが有効な場合は関連する各レコードを保存しようとしますが、関連するモデルが無効な場合は失敗しません。


編集:これは私がやろうとしていることに近いです

# t.string :name
class Game < ActiveRecord::Base
    has_one :wikipedia_paragraph
    has_one :ign_rating

    def name=(_name)
        ret = super
        self.build_wikipedia_paragraph
        self.build_ign_rating
        ret
    end
end


# t.text :paragraph
class WikipediaParagraph < ActiveRecord::Base
    belongs_to :game

    validates_presence_of :paragraph

    def game=(_game)
        ret = super
        self.paragraph = Wikipedia.find(self.game.name)
        ret
    end
end

class IgnRating..

本、映画など、ゲームと同じ構造に従うモデルが他にもあります。その場合WikipediaParagraph.paragraph == nil、ゲームは検証に失敗します。has_one :wikipedia_paragraph, :validate => falseゲームが保存され、WikipediaParagraphが保存されなかった場合は、どちらも保存せずに両方を保存したほうがいいと思います。

使うよりもエレガントなものが欲しいと思っていました

self.build_wikipedia_paragraph
self.wikipedia_paragraph = nil unless self.wikipedia_paragraph.valid?

has_one/many今では、おそらく不可能だと気づきました。

4

2 に答える 2

3

ドキュメントhttp://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_manyを確認してください。親オブジェクトが保存されると、has_many 関連付けがデフォルトで検証されることが示されています。次のように false に設定できます。

class Post < ActiveRecord::Base
    has_many :comments, :validate => false
end

validates_associatedデフォルトでアソシエーションを検証しておらず、自分で処理したい場合に役立つと思います。全体の状況は少し混乱しているので、これが役立つことを願っています.

于 2011-07-13T20:19:55.030 に答える
0

検証により、アプリケーションのビジネス ロジックが強化されます。関連するコメントの状態に関係なく、常に Post オブジェクトを保存する場合は、投稿とコメントを個別に保存できます。これにより、コメントのコレクションを繰り返し処理し、それぞれを保存して、エラーが発生した場合に続行することができます

post = Post.new
post.valid? # true

comments.each do |comment|
  comment.save # some will some wont
end

あなたが説明したように、これで問題が正確に解決されるわけではないことはわかっていますが、関連付けの検証を無効にする理由を考えるとよいでしょう。has_many 呼び出しでの :validate => false の問題は、常に検証なしで保存されることです。これは意図したものではない可能性があります。

検証を維持しながら、この問題を解決するより正統な方法はありますか?

于 2011-07-13T23:33:10.917 に答える