与模型无关的rails simple_form字段


74

我有一个与名为“订单”的模型绑定的现有表格,但是我想添加新的表格字段,以捕获信用卡信息,例如名称,抄送号码等,以便在第三方付款网关上进行处理。

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



1
该问题不是上述链接问题的重复。那是关于未连接模型的整个表格。这是关于使选定字段未连接到表单模型的问题。
Marcelo De Polli13年

2
这会给您PCI合规性带来各种各样的问题,并且非常危险!!尽管您没有将CC信息保存到数据库中,但是如果将CC信息提交到服务器,则所有详细信息都将保存在您的日志中,如果任何人都可以访问您的日志,则他们可以访问未加密的客户端CC信息。您应该完全避免将此数据提交到服务器。如果确实需要,请查看客户端加密(developers.braintreepayments.com/javascript+ruby/sdk/client/…)。否则,请使用直接邮寄表格或第三方放置工具。祝好运!
2014年

Answers:


43

您可以使用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问题Ruby中的attr_accessor是什么?

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


在提交表单后,我在控制器上有一个后续问题,如何在调用“ model.save”时“取消设置”那些与CC相关的字段,因为它可能会引发错误?
zeratool 2012年

1
您可以params.except(:card_number)在控制器中使用。
TrungLê2012年

48

如果我正确理解了您的答案,那么您将在官方Wiki页面上解释您要执行的操作:创建一个不读取attribute的伪输入。根据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

真好 我从来没有注意到。
爱德华

2
您可能必须重新启动/重新加载您的Web服务器才能进行此操作。
Fitter Man

由于某种原因,它不再起作用。undefined method merge_wrapper_options for #<FakeInput:0x007fbe5e32beb8>
Trein 2014年

@Trein您正在使用哪个版本的Rails / SimpleForm?
baxang 2014年

@baxang我正在使用v3.0.2。可以在rc版本上使用吗?不幸的是,我不能在该项目上使用rc版本(策略...)。
Trein 2014年

41

最好的处理方法是这样使用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会尝试实例化User模型,并且我们将再次收到相同的错误消息...


最简单的答案是最好的。为我工作。
emptywalls

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 -%>

6

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

只需添加input_html带有任何value键的选项即可。例如:

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

经过测试的simple_from版本:3.2.1、3.5.1

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.