如何在Ruby on Rails中创建非模型表单?

22

我正在尝试在Ruby on Rails中制作一个非模型表单,大多数我能找到的例子只有一个字段(比如搜索字段),或者使用一种旧的方式编写表单,例如用Ruby on Rails创建电子邮件表单.

如果有人可以向我展示一个非模型表单的示例代码,例如两个字段的视图和我在控制器中如何访问这些字段,我将不胜感激.

非常感谢。


我也注意到网络上有一些评论暗示非模型表单很难验证,如果是这种情况,使用“联系人表单”的“表单样式”是否更容易呢? - conspirisi
请查看validatable gem,以轻松验证非数据库对象。http://github.com/jnunemaker/validatable - Luke Francl
在验证失败时恢复输入值:https://dev59.com/RVHTa4cB1Zd3GeqPULsa#24974457 - Ciro Santilli OurBigBook.com
5个回答

35
你需要使用FormHelper方法:
假设你想要一个简单的test动作,它提交到do_test动作:
test动作的简单视图(posts/test.html.erb):
<% form_tag '/posts/do_test' do %>
    <%=label_tag 'name' %>
    <%=text_field_tag 'name'%>

    <%=label_tag 'phone' %>
    <%=text_field_tag 'phone'%>

    <div><%= submit_tag 'Save' %></div>
<% end -%>

在 posts 控制器中:

def test
end

def do_test
  name = params[:name]
  phone = params[:phone]
  # do whatever you want...
end

你还需要将这两个操作添加到config/routes.rb文件中的路由中。

map.resources :posts, :collection=>{:test => :get, :do_test => :post}

8

1
适用于Rails5也可以工作 - fguillen

7
如果你创建一个代表你的对象的类(我们称之为 ContactInfo),你可以在该类上定义方法,然后使用标准的Rails表单构建器助手来使用它们。
class ContactInfo 
  attr_accessor :name, :company, :email, :phone, :comments

  def initialize(hsh = {})
    hsh.each do |key, value|
      self.send(:"#{key}=", value)
    end
  end
end

在你的表单中:

<h2>Contact Us</h2>
<% form_for(@contact_info, :url => path_for_your_controller_that_handles_this, :html => {:method => :post}) do |f| %>

  <%= f.label :name %>
  <%= f.text_field :name %>

  ...
<% end %>

到目前为止,谁在意呢?

然而,加入validatable gem,你就有了一个真正的理由去做这个!现在你可以像真正的模型一样拥有验证消息。

看看我完成的ContactInfo类:

class ContactInfo
  include Validatable

  attr_accessor :name, :company, :email, :phone, :comments

  validates_presence_of :name
  validates_presence_of :email
  validates_presence_of :phone

  def initialize(hsh = {})
    hsh.each do |key, value|
      self.send(:"#{key}=", value)
    end
  end
end

我喜欢这个功能,因为你可以像写ActiveRecord对象一样编写控制器,而不必在需要重新显示表单时混淆它们的逻辑。
此外,如果您正在使用Formtastic或其他自定义表单构建器,则可以轻松地将此对象与之配合使用,保持现有的表单样式。

1

0

谢谢,但那看起来太高级了,我只是个初学者,如果我成为Rails忍者的话,我可能会尝试一下。 - conspirisi
一个Presenter(表现者)实际上是一个非常好的模式,适用于表示与模型没有直接关联的表单,即使对于初学者也是如此。 - yagooar

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