Railssimple_form 字段与模型无关

我有一个现有的形式是一个名为“订单”的模型绑定,但我想添加新的表单字段,将捕获信用卡信息,如名称,抄送号码等,将在第三方支付网关处理。

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

47483 次浏览

可以使用 attr _ accessor

 class Order < ActiveRecord::Base


attr_accessor :card_number




end

现在您可以执行 Order.first.card_number = '54421542122',或者以自己的形式使用它,或者执行其他任何需要执行的操作。

请点击这里查看 ruby docs < a href = “ http://www.ruby-doc.org/core-1.9.3/Module.html # method-i-attr _ accessor”rel = “ norefrer”> http://www.ruby-doc.org/core-1.9.3/module.html#method-i-attr_accessor 这里有一个有用的 stackoverflow 问题: 什么是 Ruby 中的 attr _ accessor?

不要把它和 attr _ access 混在一起

如果我没有理解错的话,你想要做的事情在官方的维基页面上有解释: 创建一个不读取属性的假输入。根据 Edward 的建议,您可以使用与任何实际数据库列无关的字段,但是如果表单字段与模型无关,则不需要在模型中定义属性。

总之,页面中解释的技巧是定义一个名为“ FakeInput”的自定义输入,并像这样使用它:

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

不要忘记在添加/修改自定义输入后重新启动 Rails 服务器,如 Fitter Man 所注释的那样。

更新: 请注意,官方维基页面已经更新和 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

另外,如果您只是试图添加一些内容并将其放入 params中,但是将其保留在模型的 hash 之外,那么您可以只使用 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 -%>

处理这个问题的最佳方法是像下面这样使用 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 会尝试实例化 User 模型,而且我们会再次得到相同的错误消息..。

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

只需添加 input_html选项,其中包含任何 value键。例如:

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

测试 simple _ from 版本: 3.2.1,3.5.1