Rails:我无法在重定向中传递validation错误

所以这是一个简单的项目,有产品,你可以出价。 想想eBay。

我按如下方式构建了项目:

$ rails new routetest $ rails g scaffold product productname reserveprice:integer $ rails g scaffold bid bidprice:integer product_id 

在我所包含的每个产品的“展示”视图中

  • 产品详情(由脚手架产生)
  • 到目前为止的出价列表
  • 使用form_for帮助程序汇总新出价的表单

 

Normal Products\Show Part

Productname:

Reserveprice:



List of bids

Product ID Bid Price


Form For Bids

Make a Bid

(params[:id]) %>

点击“提交”后,将调用出价控制器#create action。

  def create @bid = Bid.new(bid_params) if @bid.save redirect_to "/products/#{@bid.product_id}", notice: 'Bid was successfully created.' else render action: 'new' end end 

因此,成功的出价会将用户返回到产品展示视图,并将记录添加到页面的出价部分。

我在出价模型中有validates_presence_ofvalidation。 因此,如果用户将出价字段留空,则validation将失败,并且出价控制器包条操作会将出价设置为新视图。 包括错误消息。 出价新视图包括脚手架生成的代码“ etc”

我实际想要做的不是呈现新动作,而是将用户带回产品展示页面,就像成功出价只是为了在产品展示页面上显示错误消息一样。 基本上,这给用户留下了产品展示页面的感觉,而不是将它们扔到出价新页面。

我遇到的问题是如何将错误消息传回产品展示页面? 如果我编辑上面的出价控制器创建操作代码并替换“渲染操作:’新”行

 redirect_to "/products/#{@bid.product_id}" 

然后用户返回到页面,但不传递错误消息。 我认为这是因为错误消息存储为新动作(出价控制器)的呈现的一部分

所以我的问题是如何实现我想做的事情? 返回到产品展示视图并显示validation失败的错误消息。 谢谢。

PS – 我知道我需要将脚手架生成的代码“ …”代码添加到产品展示视图中,但我在上面的代码中没有这样做,因为它会导致NilMethod错误,因为错误不是为方法存在而创建的。

你想要这样的东西

 redirect_to product_path(@bid.product_id), :flash => { :error => @bid.errors.full_messages.join(', ') } 

这将重定向到产品页面,但将错误作为Flash消息传递。

一个快速选项是在bids#create action中呈现show product视图:

 if @bid.save redirect_to "/products/#{@bid.product_id}", notice: 'Bid was successfully created.' else @product = Product.find(params[:bid][:product_id]) render template: 'products/show' 

这将显示您想要的内容,但URL仍将显示为create出价路径,这可能会造成混淆。 它可能有点难以阅读,因为我们必须在两个控制器之间反弹才能完成这一任务。

更好的选择可能是将出价创建操作移动到产品控制器中。 要做到这一点,你可以……

routes.rb/products/:id/create_bid添加新路由:

 resources :products do member do post 'create_bid' end end 

在出价创建表单中使用此路线:

 

Make a Bid

<%= form_for(@bid, url: create_bid_product_path(@product)) do |b| %>

在产品控制器中定义此操作:

 def create_bid @bid = Bid.new(bid_params) if @bid.save redirect_to product_url(params[:id]), notice: 'Bid was successfully created.' else @product = Product.find(params[:id]) render action: 'show' end end 

并将bid_params方法从出价控制器复制到产品控制器中。