从另一个控制器Rails 4.0验证错误后重新填充表单

时间:2014-02-19 07:10:36

标签: ruby-on-rails

我对这个问题感到很尴尬:

我想从一个视图发布评论,如果表单中出现错误,我希望重新填充表单。我使用了渲染方法,但我的表格没有重新填充。

我指定从视图中显示表单并使用另一个控制器操作,换句话说就是:

表格来自:views / cars / show.html.erb代码如下:

<h1>Fiche détaillée</h1>

<%= @car.marque %><br>
<%= @car.modele %><br>
<%= @car.nbkm %><br>
<%= @car.couleur %><br>
<%= @car.disponibilite %><br>
<hr>

<% x=0 %>
<h1><%= pluralize(@car.comments.count, 'commentaire') %></h1>
<% @car.comments.each do |k| %>
<%= x+=1 %>
Email : <%= k.email %><br>
Sujet : <%= k.sujet %><br>
Commentaire : <%= k.commentaire %><br>
<%= link_to 'Supprimer', [k.car, k], method: :delete %><br><br>
<% end %>

<hr>

<h1>Ajouter votre commentaire</h1>
<div style='width:300px;'>

<% flash.each do |key, msg| %>
<% if msg.count >0 %>
<p class="bg-danger" style='padding:10px;'><%= pluralize(msg.count,'error') %>
  <ul><% msg.full_messages.each do |m|%>
        <li><%= m %></li>
    <% end %>
</p>
<% end %>
<% end %>
</ul>




<%= form_for([@car,@car.comments.build]) do |co| %>

<%= co.label :'Email' %><br>
<%= co.text_field :email , class: 'form-control' %><br>
<br>
<%= co.label :'Sujet' %><br>
<%= co.text_field :sujet , class: 'form-control'%><br>
<br>
<%= co.label :'Commentaire' %><br>
<%= co.text_area :commentaire , class: 'form-control' %><br>
<br>
<%= co.submit :'Envoyer votre commentaire', class: 'btn btn-info'%>

<% end %>
</div>

在我的控制器下面:

控制器1:controllers / cars_controller.rb

def create
#render text: params[:car].inspect
@car = Car.new(params[:car].permit(:marque,:modele,:nbkm,:couleur,:disponibilite))
  if !@car.save
    render 'new'
  else
    redirect_to @car
  end
end

def show
@car = Car.find(params[:id])
end

def index
@cars=Car.all
end

控制器2:controllers / comments_controller.rb

class CommentsController < ApplicationController

  def new
    @comment=Comment.new
  end

  def create

    @car = Car.find(params[:car_id])
    @comment = @car.comments.create(params[:comment].permit(:email,:sujet,:commentaire))

        if !@comment.save


          flash[:error] = @comment.errors
          flash.keep[:error]
          render 'cars/show'

          else
          redirect_to car_path(@car)
        end
  end


  def destroy
    @car = Car.find(params[:car_id])
    @comment = @car.comments.find(params[:id])
    @comment.destroy
    redirect_to car_path(@car)
  end

end

我真的不明白为什么它不起作用!!

非常感谢您的帮助;)

1 个答案:

答案 0 :(得分:0)

编辑:

我为你的情况做了一些类似的测试,问题应该归因于flash方法。

替换以下行:

flash[:error] = @comment.errors
flash.keep[:error]
render 'cars/show'

要:

flash.now[:error] = @comment.errors.full_messages
@car.reload
render 'cars/show'

由于flash[:error]仅在下一个操作中可用,因此仅适用于redirect_to,因此您必须使用flash.now[:error]来呈现相同的视图模板。最重要的是,虽然@comment的保存失败,但@car中的评论列表仍会收到评论的createbuild或{返回的实例化无效对象{1}}方法。这是因为这三个方法总是将实例化对象返回到new集合,尽管它无法保存它。所以我们必须通过@car.comments重新加载@car对象来刷新内存并从数据库中获取正确的Comment集合。


之前的回复:

在crate操作中,@car.reload方法create将直接创建并返回没有给定属性的实例化对象,然后在通过验证时尝试保存它。如果您尚未为@car.comments.create(..)模型设置验证,则会直接保存它。对集合关联尝试Comment@car.comments.new(..),在验证通过后,它不会强制保存实例化对象。另外,请检查@car.comments.build(..)模型以设置验证。