Да, я тоже это заметил.
Просто измените f.object.errors.present?
на @document.errors.any?
(или @document.errors.present?
).
Если вы действительно хотите использовать f.object.errors.present?
, напишите becomes
в контроллере (действия по редактированию и обновлению) вместо представления:
def edit
@document = Document.find(params[:id]).becomes(Document)
end
def update
@document = Document.find(params[:id]).becomes(Document)
# ....
end
А потом в представлении:
<%= form_for @document do |f| %>
<% if f.object.errors.present? %>
<p>Errrorsss....</p>
<% end %>
#.....
Это происходит потому, что URL-адрес формы создается в соответствии с @ document.becomes (Document) (=> PUT document/:id
), а @document создается в соответствии со своим «истинным» классом (подклассом Document). *
Если у вас есть pry (настоятельно рекомендуется), напишите:
def update
@document = Document.find(params[:id])
binding.pry
# ...
end
А затем осмотрите @document. Вы увидите, что @document является экземпляром LegalDocument или другого подкласса, даже если вы назвали @document.becomes(Document)
в своей форме.
Так что в финале f.object
и @document
не совпадают.
Это объясняет, почему вы не видите f.object.errors
, когда проверка не пройдена.
Редактировать
«Лучший способ» справиться с ИППП и формой - НЕ использовать becomes
:
<= form_for @document, url: { controller: 'documents', action: 'update' }, as: :document do |f| %>
<% if @document.errors.any? %>
# or if f.object.errors.any?
# handle validation errors
<% end %>
# your form...
<% end %>
Это позволяет вам:
иметь только один контроллер (documents_controller)
иметь только один ресурс (ресурсы: документы)
он отслеживает ваши подклассы: LegalDocument будет храниться как LegalDocument. Без преобразования : Вам не нужно сохранять его класс перед преобразованием в Document, а затем переназначать его позже.
Кроме того, ваш подкласс доступен в вашей форме, поэтому вы можете (давайте представим) построить select
для типа.
ваш контроллер выглядит чище: @document = Document.find params[:id]
больше ничего. Прямо как классический ресурс.
Если вы хотите поделиться этой формой с различными действиями (обычно edit
и new
):
<%= form_for @document, url: { controller: 'media_files', action: action }, as: :media_file do |f| %>%>
# edit.html.erb
<%= render 'form', action: 'update' %>
# new.html.erb
<%= render 'form', action: 'create' %>