Странное поведение Ruby on Rails с обработкой ошибок ActiveRecord - PullRequest
0 голосов
/ 22 апреля 2010

Может кто-нибудь объяснить, почему это происходит?

mybox:$ ruby script/console
Loading development environment (Rails 2.3.5)
>> foo = Foo.new
=> #<Foo id: nil, customer_id: nil, created_at: nil, updated_at: nil>
>> bar = Bar.new
=> #<Bar id: nil, bundle_id: nil, alias: nil, real: nil, active: true, list_type: 0, body_record_active: false, created_at: nil, updated_at: nil>
>> bar.save
=> false
>> bar.errors.each_full { |msg| puts msg }
Real can't be blank
Real You must supply a valid email
=> ["Real can't be blank", "Real You must supply a valid email"]

Пока все отлично, вот что я хочу прочитать в сообщении об ошибке. Теперь больше:

>> foo.bars << bar
=> [#<Bar id: nil, bundle_id: nil, alias: nil, real: nil, active: true, list_type: 0, body_record_active: false, created_at: nil, updated_at: nil>]
>> foo.save
=> false
>> foo.errors.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n  <error>Bars is invalid</error>\n</errors>\n"

Это то, что я не могу понять. Почему я получаю Бары недействительно по сравнению с сообщениями об ошибках, показанными выше, ["Реальный не может быть пустым", "Реальный, вы должны указать действительный адрес электронной почты"] и т. Д.

В моем контроллере просто есть метод response_to со следующим:

 format.xml  { render :xml => @foo.errors, :status => :unprocessable_entity }

Как я могу выводить настоящие сообщения об ошибках, чтобы пользователь имел некоторое представление о том, что он сделал неправильно? Как мне написать свой метод рендеринга в моем контроллере, чтобы показать все соответствующие сообщения об ошибках?

Ответы [ 3 ]

1 голос
/ 22 апреля 2010

Я думаю, что вы используете

validates_associated: bar в вашей модели foo.rb

так что он только дает "Бары недействительны"

чтобы проверить сообщения об ошибках для баров, либо вы должны выполнить следующие действия в вашем

VIEW

<%= error_messages_for :foo, :bar %>

Контроллер

foo.bar.errors.to_xml

& чтобы пропустить сообщение "bar is invalid", поместите следующий метод в foo.rb

  def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %w{ bar }.include?(err.first) }
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end
0 голосов
/ 24 апреля 2010

Мы использовали для перезаписи метод errors в конкретной модели, если нам также требовались ошибки дочерних объектов, что-то вроде этого

class Foo < ActiveRecord::Base

  alias :errors_without_children :errors

  def errors
    self.bars.each do |i|
      i.errors.each_full do |msg|
        errors_without_children.add_to_base msg
      end
    end
    errors_without_children
  end

end

Вы все еще можете оптимизировать его больше.Но этот уже добавляет сообщения об ошибках всех объектов баров в foo.

0 голосов
/ 22 апреля 2010

Это потому, что ошибки для bar хранятся в объекте bar. Чтобы получить эти ошибки, вы должны сделать что-то вроде этого:

foo.bar.each do |bar|
  bar.errors.each_full { |msg| puts msg }
end

Это все запутанно для меня, но я не нашел лучшего способа собрать все ошибки в одном списке (кроме того, как обрабатывать его самостоятельно) Я понимаю причину этого (поскольку каждый объект должен знать только о своих собственных ошибках). Обычно я выполняю экстент ActiveRecord::Errors и создаю новую функцию each_full_with_associations, которая возвращает их все.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...