提交form_for时路由参数不可用?

时间:2017-02-26 19:10:53

标签: ruby-on-rails forms routes erb form-for

为什么我提交表单时收到此错误?我还没有建立身份证吗?

ActiveRecord::RecordNotFound at /polls/:poll_id/responses
Couldn't find Poll with 'id'=

在我的Polls_Controller我正在使所有表单输入都可访问。 poll_id来自路线参数,展示路线成功响应:id

def show
  @poll_options = @poll.options

  # since you can respond to a poll from its show route
  @poll_response = PollResponse.new
end

def responses
  @poll_response = PollResponse.create(
    params.require(:poll_response).permit(:poll_option_id, :ip_address, :poll_id)
  )
  if @poll_response.save
    redirect_to "/welcome"
  else
  end
end

private

def set_poll
  @poll = Poll.find(params[:id])
end

我的show视图在/polls/:id成功加载,但是,当我提交表单时,看起来Rails因为路由更改而失去对该参数的访问权。

#Poll/Show.html.erb
<%= form_for(@poll_response, url: '/polls/:poll_id/responses/') do |f| %>

  <%= f.hidden_field(:ip_address, value: request.remote_ip) %>
  <%= f.hidden_field(:poll_id, value: @poll.id) %>
  <ul>
    <% @poll_options.each do |option_id, option_value| %>
      <li>
        <%= f.radio_button(:poll_option_id, option_id) %>
        <%= option_value %> </br>
      </li>
    <% end %>
  </ul>
  <%= f.submit "Vote!" %>

<% end %>

这是我的路线。 Poll_Response和Poll_Option模型属于民意调查。

resources :polls, only: [:show, :create, :index, :responses] do
  post 'responses', as: :responses
end

1 个答案:

答案 0 :(得分:1)

这里有一些问题。

首先,表单的url: '/polls/:poll_id/responses/'选项意味着表单在提交表单时将使用文字路由/polls/:poll_id/responses/form_for并不了解您#&# 39;重新期望用任何东西取代:poll_id,以免它赢了。

接下来,当您/polls/:id/responses时,路线应显示为rake routes,因此路线本身可能在routes.rb中未正确定义。您的routes.rb看起来应该更像这样:

resources :polls, only: [:show, :create, :index, :responses] do
  member do
    post :responses
  end
end

这会为您提供类似/polls/:id/response的路线,您也可以将set_poll控制器回调附加到responses路线。现在当你rake routes时,你应该看到:

responses_poll POST /polls/:id/responses(.:format) polls#responses

您的表单有responses_poll_path网址帮助:

<%= form_for(@poll_response, url: responses_poll_path(@poll) do |f| %>

您也可以删除:

<%= f.hidden_field(:poll_id, value: @poll.id) %>

来自您的表单,因为民意调查id现在位于其所属的路线中。

通过上述更改,您的表单将发布到正确的控制器,该控制器中的params[:id]将识别相关投票,而@poll将是responses内正确的内容控制器。

现在您已正确设置路由和表单,您的控制器变得非常简单:

@poll_response = @poll.responses.create(
  params.require(:poll_response).permit(:poll_option_id, :ip_address)
)

@poll.responses关联应自动提供投票id(如果您当前has_many :responses内有app/models/poll.rb