rails的simple_form字段与模型无关

我有一个现有的表格绑定到一个名为“订单”的模型,但我想添加新的表单域,将捕获信用卡信息,如姓名,cc号码等在第三方支付网关处理。

但是因为我不想在我们的数据库中保存CC信息,所以在我的订单表中没有相应的列。 当提交表单时,这些信用卡input字段不是订单模型的“部分”,这给了我一个错误。

你可以使用attr_accessor

class Order < ActiveRecord::Base attr_accessor :card_number end 

现在你可以做Order.first.card_number = '54421542122'或者在你的表单中使用它或者你需要做的任何事情。

看到这里的ruby文档http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor和这里有一个有用的stackoverflow问题什么是attr_accessor在Ruby中?;

不要混淆attr_accessible! attr_accessor和attr_accessible之间的区别

如果我正确理解你的答案,你想要做的是在这里的官方wiki页面中解释: 创build一个不读取属性的假input 。 根据Edward的build议,您可以使用与任何实际数据库列无关的字段,但是如果表单字段与模型无关,则不需要在模型中定义属性。

总之,页面中解释的技巧是定义一个名为“FakeInput”的自定义input,并使用如下所示:

 <%= simple_form_for @user do |f| %> <%= f.input :agreement, as: :fake %> .... 

在Fitter Man评论添加/修改自定义input之后,不要忘记重新启动您的Rails服务器。

更新:请注意官方维基页面已经更新 , 维基页面上的示例代码不适用于那些使用旧版本的SimpleForm。 如果遇到类似undefined method merge_wrapper_options for...的错误,请使用下面的代码。 我正在使用3.0.1,这个代码运行良好。

 class FakeInput < SimpleForm::Inputs::StringInput # This method only create a basic input without reading any value from object def input template.text_field_tag(attribute_name, input_options.delete(:value), input_html_options) end end 

处理这个问题的最好方法是使用simple_fields_for像这样:

 <%= simple_form_for @user do |f| %> <%= f.input :first_name %> <%= f.input :last_name %> <%= f.input :email %> <%= simple_fields_for :other do |o| %> <%= o.input :change_password, as: :boolean, label: 'I want to change my password' %> <% end %> <% end %> 

在这个例子中,我添加了一个名为change_password的新字段,它不是底层user模型的一部分。

这是一个好办法,原因是它可以让你使用任何简单的表单input/包装作为领域。 我不在乎@baxang的答案,因为它不允许你使用不同types的input。 这似乎更灵活。

注意,虽然这个工作,我不得不通过:other simple_fields_for只要没有同名的模型,就可以传递任何string/符号。

即不幸的是我不能传递:user ,因为simple_form将尝试实例化用户模型,我们会再次得到相同的错误消息…

另外,如果你只是想添加一些东西,并将其放入params ,但是将其从模型的哈希值中排除,则可以使用FormTagHelpers。 http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html

例:

  <%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %> <%= devise_error_messages! %> <% resource.class.invite_key_fields.each do |field| -%> <%= f.input field %> <%= hidden_field_tag :object_name, @object.class.name %> <%= hidden_field_tag :object_id, @object.id %> <% end -%>