我有一个与名为“订单”的模型相关联的现有表单,但我想添加新的表单字段,这些字段将捕获信用卡信息,例如姓名、抄送号码等,以便在第 3 方支付网关上进行处理。
但是由于我不想在我们的数据库中保存 CC 信息,所以我的订单表中没有相应的列。这在提交这些信用卡输入字段不是订单模型的“一部分”的表单时给了我一个错误。
我有一个与名为“订单”的模型相关联的现有表单,但我想添加新的表单字段,这些字段将捕获信用卡信息,例如姓名、抄送号码等,以便在第 3 方支付网关上进行处理。
但是由于我不想在我们的数据库中保存 CC 信息,所以我的订单表中没有相应的列。这在提交这些信用卡输入字段不是订单模型的“一部分”的表单时给了我一个错误。
如果我正确理解您的答案,您想要做的将在此处的官方 wiki 页面中进行说明:创建不读取属性的虚假输入。根据 Edward 的建议,您可以使用与任何真实数据库列无关的字段,但是如果表单字段与模型无关,则无需在模型中定义属性。
总之,页面中解释的技巧是定义一个名为“FakeInput”的自定义输入,并像这样使用它:
<%= simple_form_for @user do |f| %>
<%= f.input :agreement, as: :fake %>
....
正如 Fitter Man 评论的那样,在添加/修改自定义输入后不要忘记重新启动您的 Rails 服务器。
更新:请注意官方 wiki 页面已更新,wiki 页面上的示例代码不适用于使用旧版本 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
您可以使用 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 问题What is attr_accessor in Ruby?
不要将它与 attr_accessible 混淆! attr_accessor 和 attr_accessible 的区别
处理此问题的最佳方法是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
模型的一部分。
这是一个好方法的原因是它允许您使用任何简单的表单输入/包装器作为字段。我不关心@baxang 的答案,因为它不允许您使用不同类型的输入。这似乎更灵活。
请注意,要使其正常工作,我必须传递:other
给simple_fields_for
. 只要没有同名的模型,您就可以传递任何字符串/符号。
即不幸的是我不能通过: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 -%>
我发现了一个非常简单(而且有些奇怪)的解决方法。
只需在里面添加input_html
带有任何value
键的选项。例如:
= simple_form_for @user do |f|
= f.input :whatever, input_html: {value: ''}
测试 simple_from 版本:3.2.1、3.5.1