ActiveModel: отключить сбой проверки при сбое связанных моделей - PullRequest
1 голос
/ 14 июля 2011

Всегда ли 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..

Есть еще модели, которые следуют той же структуре, что и Game, например, Book, Movie.Если WikipediaParagraph.paragraph == nil, то игра не проходит проверку.Я бы предпочел, чтобы игра сохранялась, а WikipediaParagraph - нет, но has_one :wikipedia_paragraph, :validate => false делает и то, и другое без сохранения.

Я надеялся на что-то более элегантное, чем использование

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

длякаждый has_one/many но теперь я понимаю, что это, вероятно, невозможно.

Ответы [ 2 ]

3 голосов
/ 14 июля 2011

Ознакомьтесь с документацией http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many. Это показывает, что ассоциация has_many проверяется по умолчанию при сохранении родительского объекта. Вы можете установить его в false, как это:

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

Полагаю, validates_associated может пригодиться, если вы по умолчанию не проверяете ассоциацию и хотите самостоятельно ее обработать. Вся эта ситуация немного сбивает с толку, поэтому я надеюсь, что это поможет.

0 голосов
/ 14 июля 2011

Ваши проверки обеспечивают соблюдение бизнес-логики вашего приложения.Если вы всегда хотите сохранить объект Post, независимо от состояния связанных комментариев, вы можете сохранять записи и комментарии независимо друг от друга.Это позволит вам перебирать коллекцию комментариев и пытаться сохранить каждый из них, продолжая, если есть ошибка

post = Post.new
post.valid? # true

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

Я знаю, что это не совсем решает вашу проблему, как вы ее описали,но может быть полезно подумать о том, почему вы хотите отключить проверки для ассоциации.Проблема с: validate => false в вызове has_many заключается в том, что он всегда будет сохранять без проверки, что может не соответствовать вашим намерениям.

Существует ли более ортодоксальный способ решения этой проблемы при сохранении проверки?

...