Ruby-on-rails rails simple_form 字段与模型无关
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12146466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
rails simple_form fields not related to the model
提问by zeratool
I have an existing form which is tied to a model named 'Order', but i want to add new form fields that will capture Credit Card info such as name, cc number, etc to be processed on a 3rd party payment gateway.
我有一个与名为“订单”的模型相关联的现有表单,但我想添加新的表单字段,这些字段将捕获信用卡信息,例如姓名、抄送号码等,以便在 3rd 方支付网关上进行处理。
But since i don't want to save CC info in our database, there are no corresponding columns of that in my order table. And this gives me an error when submitting the form that those Credit card input fields are not 'part' of the order model.
但是由于我不想将 CC 信息保存在我们的数据库中,因此我的订单表中没有相应的列。这在提交表单时给我一个错误,即那些信用卡输入字段不是订单模型的“一部分”。
采纳答案by Edward
You can use attr_accessor
您可以使用 attr_accessor
class Order < ActiveRecord::Base
attr_accessor :card_number
end
Now you can do Order.first.card_number = '54421542122'or use it in your form or whatever else you need to do.
现在您可以Order.first.card_number = '54421542122'在您的表单或任何您需要做的事情中执行或使用它。
See here for ruby docs http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessorand here for a useful stackoverflow question What is attr_accessor in Ruby?
请参阅此处了解 ruby 文档http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-attr_accessor和此处了解一个有用的 stackoverflow 问题Ruby 中的 attr_accessor 是什么?
Don't get it mixed up with attr_accessible! Difference between attr_accessor and attr_accessible
不要将它与 attr_accessible 混淆! attr_accessor 和 attr_accessible 的区别
回答by baxang
If I understand your answer correctly, what you want to do is explained in the official wiki page here: Create a fake input that does NOT read attributes. You can use a field not related to any real database column by Edward's suggestion, however you don't need to define an attribute in your model if the form field is nothing to do with the model.
如果我正确理解了您的答案,那么您想要做的将在此处的官方 wiki 页面中进行说明:Create a fake input that does not read attributes。根据 Edward 的建议,您可以使用与任何实际数据库列无关的字段,但是如果表单字段与模型无关,则不需要在模型中定义属性。
In summary, the trick explained in the page is defining a custom input called 'FakeInput' and use it like this:
总之,页面中解释的技巧是定义一个名为“FakeInput”的自定义输入,并像这样使用它:
<%= simple_form_for @user do |f| %>
<%= f.input :agreement, as: :fake %>
....
Do not forget to restart your rails server after adding/modifying a custom input as Fitter Man commented.
在添加/修改自定义输入后,不要忘记重新启动 Rails 服务器,正如 Fitter Man 评论的那样。
UPDATE:Please note that the official wiki page has updatedand the sample code on the wiki page is not working for those which use older versions of SimpleForm. Use code below instead if you encounter an error like undefined method merge_wrapper_options for.... I'm using 3.0.1 and this code works well.
更新:请注意官方 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
回答by asgeo1
The best way to handle this is to use simple_fields_forlike so:
处理这个问题的最好方法是这样使用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 %>
In this example, I have added a new field called change_passwordwhich is not part of the underlying usermodel.
在此示例中,我添加了一个名为的新字段change_password,该字段不属于基础user模型的一部分。
The reason this is a good approach, is that it lets you use any of the simple form inputs / wrappers as fields. I don't care for the answer by @baxang, because it doesn't allow you to use different types of inputs. This seems more flexible.
这是一个好方法的原因是它允许您使用任何简单的表单输入/包装器作为字段。我不在乎@baxang 的答案,因为它不允许您使用不同类型的输入。这似乎更灵活。
Notice though for this to work, I had to pass :otherto simple_fields_for. You can pass any string/symbol as long as there is not a model with that same name.
请注意,要使其正常工作,我必须传递:other给simple_fields_for. 只要没有同名的模型,您就可以传递任何字符串/符号。
I.e. unfortunately I can't pass :user, as simple_form would try to instantiate a User model, and we'd get the same error message again...
即不幸的是我不能通过:user,因为 simple_form 会尝试实例化一个 User 模型,我们会再次收到相同的错误消息......
回答by Richard Ortega
Also if you're just trying to add something and get it into the params, but leaving it out of the model's hash, you could just do FormTagHelpers. http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
此外,如果您只是想添加一些内容并将其放入 . params,但将其排除在模型的哈希之外,则可以只执行 FormTagHelpers。 http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
Example:
例子:
<%= 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 -%>
回答by user1201917
I found a very simple (and somewhat strange) workaround.
我发现了一个非常简单(而且有点奇怪)的解决方法。
Just add the input_htmloption with any valuekey inside. E.g:
只需添加input_html带有任何value键的选项即可。例如:
= simple_form_for @user do |f|
= f.input :whatever, input_html: {value: ''}
Tested simple_from versions: 3.2.1, 3.5.1
测试 simple_from 版本:3.2.1、3.5.1

