为嵌套的Ruby on Rails资源渲染新表单

时间:2012-04-29 01:25:49

标签: ruby-on-rails ruby rails-routing

在我的Ruby on Rails应用程序中,每个组都有_many:expenses。我已经嵌套了我的路线,因此费用仅作为其父组的子实体输入。这是routes.rb的摘录。

resources :groups do
    resources :expenses
end

如果通过/ groups /:group_id / expenses / new提交费用而不保存,我无法弄清楚如何呈现'新'操作。在我的expense_controller.rb中,以下是创建操作的定义方式:

def create
    @expense = Expense.new(params[:expense])
    @expense.group_id = params[:group_id]
    if @expense.save
      redirect_to group_expense_path(@expense.group.id, @expense.id)
    else
      render 'new'
    end
end

如果我确定费用验证并且@ expense.save结束工作,那么一切正常。但是,当它失败并且代码尝试呈现'new'时,我得到:

undefined method `expenses_path' for #<#<Class:0x007fd408b1fd58>:0x007fd408f21ca8>

所以,我假设我的嵌套路由有问题。如何将用户返回到新表单但仍然通过flash []向他/她显示错误与他们最初尝试提交的数据相关?

3 个答案:

答案 0 :(得分:0)

您需要在视图中明确指定form_for的网址。

像...一样的东西。

<%= form_for @expense, :url => group_expenses_path(@group.id) do |f| %>
  ...
<% end %>

答案 1 :(得分:0)

问题是@group未初始化

所以在你的控制器中只需做

@expense = Expense.new(params[:expense])
@group = Group.find(params[:group_id])
@expense.group_id = @group.id

答案 2 :(得分:0)

在您的<%= form_for %>中,您使用@group作为网址,因为费用属于组。但是在控制器中的创建操作中,您尚未定义@group,所以首先应将其定义为:

@expense = Expense.new(params[:expense])
@group = Group.find(params[:group_id])
@expense.group_id = @group.id

另外,我建议您在控制器中使用respond_to

respond_to do |format|
  if @expense.save
    format.html { redirect_to group_expense_path(@group.id, @expense.id), :notice => "Any msg you want" }
  else
    format.html { render :action => "new" }
  end
end

所有这些都在控制器内的创建动作中 同样针对不同的渲染方法查找:http://guides.rubyonrails.org/layouts_and_rendering.html

希望这有帮助!