Ruby on Rails中的表单,如何在不同表单之间传递变量

3
我试图在表单之间传递变量,但不幸的是我没有成功。
在我的index.html.erb文件中,我有一个名为SearchInput的文本字段,我想将这个变量传递给下一个表单search.html.erb,以便我可以相应地填充一些数据。请问我该如何做?
在我的index.html.erb文件中,我有以下内容: ``` <% form_tag (:action => 'search') do %> ```
我真的不知道如何处理这个问题,请帮忙提供一些提示,万分感谢!
3个回答

29

看起来你可以从Rails这样的MVC框架的Model、View和Controller之间的交互中受益。我建议阅读官方入门指南

以下是与你的问题相关的详细信息:

当接收到HTTP请求时,Rails会根据URL路径将请求路由到一个控制器操作。然后,控制器通过在请求上下文中评估视图模板来构建适当的响应。在Rails中的标准流程是,控制器将从params哈希中提取信息,以查询数据库获取所需的信息以构建视图。在此操作期间由该控制器设置的实例值(名称以“@”开头的变量)将在由该控制器呈现的视图中可用。

一般来说,表单会在客户端的Web浏览器中点击提交按钮时将请求直接发送到指定的URL。这个请求包含了表单字段及其值作为数据的头部。

Rails解释表单数据和params哈希中的任何其他参数。您可以在任何操作的控制器或视图中访问它们。访问params哈希的通常接受的位置是在控制器中。

让我们通过实际发生的过程走一遍。假设我们正在开发中运行服务器,前提是您已经正确设置了产品控制器的路由。

  1. 用户在地址栏输入http://localhost:3000/products,以启动GET请求。

  2. Rails将此请求路由到产品控制器的索引操作。

  3. Rails将执行ProductsController#index(位于app/controllers/products_controller.rb中的index方法)

  4. 除非您明确地呈现或重定向请求,否则Rails将呈现products/index模板(app/views/products/index.html.erb),其中包含提交给ProductsController搜索操作的小表单。表单代码如下:

    <% form_tag(:action => 'search') do %>
      <%= text_field_tag "SearchInput" %>
      <%= submit_tag %>
    <% end %>
    
  5. 用户填写SearchInput字段并将表单作为POST请求提交到 http://localhost:3000/products/search

  6. Rails将此请求路由到产品控制器的search操作。

  7. Rails执行ProductsController#search,params哈希包含用户输入到SearchInput字段中的值,其键名为SearchInput。这是一个非常简单的示例,演示如何使用表单输入来执行搜索。

  8. def search
      @products = Product.find_by_name(params["SearchInput"])
    end
    
    除非你明确地渲染或重定向请求,否则Rails将呈现产品/搜索模板(app/views/products/search.html.erb)。示例搜索视图:
    <% if @products.empty? %>
      No products found
    <% else %>
      <% @products.each do |product| %>
        <%= link_to product.name, product_url(product)%> 
        <br />
      <% end %>
    <% end %>
    

没问题,只要记住解决方案中的搜索操作非常简单,只能找到完全匹配的结果。在实际应用中,您需要使用适当的搜索插件,如ferret、sphinx、solr、xapian等。 - EmFi

2

表单数据作为params[..]哈希的一部分传递。因此,您可以以这种方式访问通过表单传递的大多数数据。

在您的情况下,您的视图

<form action="..." method="...">
  <input type=".." name="search_input" ... />
  ...
  ...
  <button>submit</button>
</form>

这些内容将通过您的控制器进行获取。

def action_name
  @collection = Model.find(:conditions => {:column_name => params['search_input']})
  ...
  ...
end

1
很抱歉,我作为一个 Ruby on Rails 的新手,真的不太理解这个问题。请问我应该把哪些文件放在哪里呢? :s - Erika
我稍微扩展了一下示例,希望能有所帮助。 - nowk

0

以下是如何通过link_to方法传递参数,以便跳转到另一个表单并使用传递的参数创建新对象。这种策略允许您在控制器中的不同操作之间传递变量并创建具有预定义属性的对象:

假设您有一个名为@foo的变量,您想将其传递给您的new控制器操作,并且您的new视图包含一个供用户填写的表单。在这种情况下,您可以使用

<%= link_to "Link Text", new_widget_path(:foo => @foo) %>

这将把 @foo 存储在 params[:foo] 中,使您可以在控制器中使用 params[:foo]。

单击 Link Text 将引导 Rails 到 WidgetController 的 new 动作。您可以拥有

def new
  @widget = Widget.new(:foo => params[:foo])
end

这将定义一个新的Widget对象,其中:foo属性预填充为params [:foo]。

然后,在您的new.html.erb视图文件中,您可以通过隐藏表单字段允许用户创建一个新的Widget对象,并已经填写了这个预定义的foo属性:

 <%= form_for(@widget) do |f| %>
  <%= f.label :other_attribute %><br />
  <%= f.text_field :other_attribute %>
  <%= f.hidden_field :foo %>
  <%= f.submit %>
<% end %>

允许用户使用自定义的other_attribute和已填充的foo属性创建一个新的Widget对象!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接