74

我有一个与名为“订单”的模型相关联的现有表单,但我想添加新的表单字段,这些字段将捕获信用卡信息,例如姓名、抄送号码等,以便在第 3 方支付网关上进行处理。

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

4

5 回答 5

48

如果我正确理解您的答案,您想要做的将在此处的官方 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
于 2013-02-02T06:21:00.163 回答
44

您可以使用 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 的区别

于 2012-08-27T17:27:52.967 回答
42

处理此问题的最佳方法是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 的答案,因为它不允许您使用不同类型的输入。这似乎更灵活。

请注意,要使其正常工作,我必须传递:othersimple_fields_for. 只要没有同名的模型,您就可以传递任何字符串/符号。

即不幸的是我不能通过:user,因为 simple_form 会尝试实例化用户模型,并且我们会再次收到相同的错误消息......

于 2015-10-21T04:42:27.517 回答
14

此外,如果您只是想添加一些东西并将其放入 中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 -%>
于 2013-04-17T05:54:32.907 回答
7

我发现了一个非常简单(而且有些奇怪)的解决方法。

只需在里面添加input_html带有任何value键的选项。例如:

= simple_form_for @user do |f|
  = f.input :whatever, input_html: {value: ''}

测试 simple_from 版本:3.2.1、3.5.1

于 2018-09-27T18:48:49.717 回答