Rails 5.如何从form_tag提交到自定义操作?

时间:2017-10-07 17:21:16

标签: ruby-on-rails ruby forms submit action

我是Ruby和Rails的真正新手,我一直在寻找解决方案两天。我需要将form_tag中的数据提交给操作' 创建'在我的控制器中添加新条目到数据库,但看起来我做了一些非常错误的事情,因为绝对没有任何反应,而且似乎form_tag甚至没有重定向到所需的操作。 这是页面代码:

<h1>Todos</h1>
<% @projects.each do |project| %>
    <tr>
      <h2><%= project.title %></h2>
      <% project.todos.each do |todo| %>
      <ul style="list-style-type:disc">
        <li><%= todo.text %></li>
      </ul>
      <% end %>
    </tr>
  <% end %>

  <%= form_tag({controller: "mega", action: "create"}, method: "get", remote: true) do %>
  <h2>New todo</h2>
  <p>
    <%= text_field_tag 'text' %>
  </p>
  <p>
    <%= select_tag 'title',  options_from_collection_for_select(@projects, 'id', 'title') %>
  </p>
  <p>
    <%= link_to 'CANCEL' %>
    <%= link_to 'OK', "", :onclick => "$('#form_id').submit()" %>
  </p>
<% end %>

控制器:

class MegaController < ApplicationController
  def index
    @projects = Project.all
    @todos = Todo.all
  end

  def update
  end

  def create
    @newTodo = Todo.create(text: params[:text])
    @newProject = Project.find_by(title: params[:title])
    @newProject.todos << @todo
    @newTodo.save
  end
end

我的路线档案。我真的不知道它是如何运作的:

Rails.application.routes.draw do
  get 'mega/index'

  root 'mega#index'

  get 'mega/update'

  post 'mega/create'

  resources :todos
  resources :projects

end

1 个答案:

答案 0 :(得分:2)

您可以使用POST请求创建资源。 从不GET。

GET请求应该是幂等的 - 它们不应更新或更改服务器上的资源。一个非常重要的原因是它们存储在浏览器的历史记录中,因此按下后退按钮将对用户造成意想不到的后果。

在Rails中调整MVC而不是在路径路径上添加动作名称,而不是使用HTTP动词来创建到正确动作的路径:

GET   /things    things#index
POST  /things    things#create

我不会试图挽救你的代码(它有很大的缺陷),而是告诉你如何解决这个问题,因为它更简单:

<%= form_for(Todo.new) do |f| %>
  <h2>New todo</h2>
  <%= f.text_field :text %>
  <%= f.collection_select(:project_id,  @projects, :id, :title, prompt: true) %>
  <%= f.submit %>
<% end %>

这将提交给todos#create - 如果您想将其路由到非常规操作,则可以使用url选项:

<%= form_for(Todo.new, url: polymorphic_path(controller: 'foo', action: 'bar')) do |f| %>

在打破规则之前学习规则是最好的。