Показать ошибки ассоциации в форме - PullRequest
1 голос
/ 26 марта 2012

У меня есть модель: review.rb

class Review < ActiveRecord::Base
  validates :title, :presence => true
  belongs_to :product
end

модель: product.rb

class Product < ActiveRecord::Base
  validates :name, :presence => true

  has_many :reviews, :dependent => :destroy
end

и эта форма: _form.html.haml

=form_for([@product, @product.reviews.build]) do |f|
  .field
    =f.label :title
    %br
    =f.text_field :title

с этим контроллером reviews_

def create
  @product = Product.find(params[:product_id])
  @review = @product.reviews.create(params[:review])
  redirect_to product_path(@product)
end

Когда я добавляю рецензию без заголовка, рецензия не создается, потому что заголовок необходим (что хорошо). Я не уверен, как заставить ошибки отображаться в этой ассоциации.

Я пробовал это:

=form_for([@product, @product.reviews.build]) do |f|
  -if @product.reviews.errors.any?
    .errors
      %h2
        =pluralize(@product.reviews.errors.count, "error")
      %ul
        =@product.reviews.errors.full_messages.each do |msg|
          %li
            =msg

но получил эту ошибку:

undefined method `errors' for #<ActiveRecord::Relation:0x00000103e31df0>

Я пробовал это:

  -if @review.errors.any?
    .errors
      %h2
        =pluralize(@review.errors.count, "error")
      %ul
        =@review.errors.full_messages.each do |msg|
          %li
            =msg

и получил:

undefined method `errors' for nil:NilClass

В контроллере, когда я:

    raise @review.errors.inspect

Я вижу ошибки:

#<ActiveModel::Errors:0x00000103d88c28 @base=#<Review id: nil, title: "", description: "", rating: nil, helpful: nil, product_id: 1, created_at: nil, updated_at: nil>, @messages={:title=>["can't be blank", "is too short (minimum is 5 characters)"]}>

Что я забыл? Как мне показать ошибки?

Спасибо

1 Ответ

3 голосов
/ 26 марта 2012

Когда вы делаете вызов redirect_to product_path(@product), вы вызываете другое действие контроллера, а именно действие Products#show.Переменные экземпляра, ваши представления будут сброшены.Возможно, вы не инициализируете переменную экземпляра @review в этом действии, поэтому вы получаете исключение.

Вам нужно что-то вроде этого

# posts_controller.rb
def show
  @product = Product.find(params[:product_id])
  @review = @product.reviews.build
end

# show.html.erb
= form_for([@product, @review]) do |f|
  -if @review.errors.any?
    .errors
      %h2
        =pluralize(@review.errors.count, "error")
      %ul
        =@review.errors.full_messages.each do |msg|
          %li
            =msg

# reviews_controller.rb
def create
  @product = Product.find(params[:product_id])
  @review = @product.reviews.build(params[:review])
  if @review.save
    redirect_to product_path(@product)
  else
    render 'products/show'
  end
end

Ключ в том, что, если review будет неудачно создан, вы будете повторно визуализировать страницу с теми же переменными экземпляра без изменений.

...