在表单中显示关联错误

Ada*_*amT 3 ruby ruby-on-rails associations ruby-on-rails-3

我有一个模型:review.rb

class Review < ActiveRecord::Base
  validates :title, :presence => true
  belongs_to :product
end
Run Code Online (Sandbox Code Playgroud)

型号:product.rb

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

  has_many :reviews, :dependent => :destroy
end
Run Code Online (Sandbox Code Playgroud)

和这个表格:_form.html.haml

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

有了这个评论控制器:

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

当我添加没有标题的评论时,评论不会被创建,因为标题是必需的(这很好)。我不确定如何让错误显示在这个关联上。

我试过这个:

=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
Run Code Online (Sandbox Code Playgroud)

但得到这个错误:

undefined method `errors' for #<ActiveRecord::Relation:0x00000103e31df0>
Run Code Online (Sandbox Code Playgroud)

我试过这个:

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

并得到:

undefined method `errors' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)

在控制器中,当我:

    raise @review.errors.inspect
Run Code Online (Sandbox Code Playgroud)

我可以看到错误:

#<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)"]}>
Run Code Online (Sandbox Code Playgroud)

我忘记了什么?如何显示错误?

谢谢

Car*_*III 6

当您调用 时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
Run Code Online (Sandbox Code Playgroud)

关键是,如果review创建失败,您将使用相同的实例变量完整地重新渲染页面。