Is it possible to use Simple Form (by: Plataformatec) without a model?
- 
                    Maybe [my answer to the other question][1] helps you. [1]: http://stackoverflow.com/a/14659270/157816 – baxang Feb 02 '13 at 06:32
- 
                    Check out http://stackoverflow.com/questions/12146466/rails-simple-form-fields-not-related-to-the-model – netwire Aug 13 '13 at 02:11
6 Answers
You can use :symbol as the first argument.
<%= simple_form_for :user, url: users_path do |f| %>
  <%= f.input :name, as: :string %>
  ...
<% end %>
It will output something like this:
<form novalidate="novalidate" class="simple_form user" action="/users" accept-charset="UTF-8" method="post">
  ...
  <div class="input string required user_name">
    <label class="string required" for="user_name">
      <abbr title="required">*</abbr> Name
    </label>
    <input class="string required" type="text" name="user[name]" id="user_name" />
  </div>
  ...
</form>
 
    
    - 36,666
- 8
- 50
- 57
- 
                    Kind of pointless though isn't it? You don't get any of the benefits of simple_form_for when you're using the fallback textfield generators. – toxaq Jul 20 '12 at 23:23
- 
                    4@toxaq Maybe that's not a good example. You can use `f.input :name, :as => :string` and generate your usual form with label, hints, etc. – htanata Jul 20 '12 at 23:48
- 
                    9Oddly that's exactly what I'm trying to do and having no success. Your example gives an `undefined method 'name?' for nil:NilClass` for me at least. – toxaq Jul 21 '12 at 00:11
- 
                    11This option still uses a model under the covers. The symbol should match a model name, it will resolve to a model and create a new one and use it on every field, so the properties used in the form fields should actually exists in the model. – Miguel Madero Jul 02 '13 at 19:32
- 
                    22I don't understand why this is the accepted answer, because the answer is just wrong. – Phillipp Sep 16 '14 at 14:27
- 
                    Well, I won't say the answer is wrong, but it seems to miss the whole point of the question. Unless I'm missing it? – codenoob Nov 09 '14 at 17:11
- 
                    1Yeah, I think I missed the point previously, and I've written a better answer as [comment](http://stackoverflow.com/questions/5181143/simple-form-without-for-non-model-form/5181627?noredirect=1#comment15335055_5181627). I've updated the answer so it does what simple_form is supposed to do. – htanata Nov 10 '14 at 17:37
- 
                    Still problem is how to autofill those inputs, if form is used for report generation for example. Tried to used hash instead of ActiveRecord object with no luck. – nazar kuliyev Nov 24 '15 at 08:21
- 
                    This worked for me, but had to include `input_html: { value: nil }` to avoid `undefined method 'name'` error – AlexGuti Mar 21 '16 at 11:49
Unfortunately simple_form relies on using a model. Essentially it would be nice to have something like simple_form_tag and input_tag methods equivalent to their rails *_tag helpers. Until then, there's an easy work around.
Use a symbol instead of the class in the form and pass the value explicitly to prevent simple_form from trying to access the model properties.
<%= simple_form_for :user, :url => '/users' do |f| %>
  <%= f.text_field :name, input_html: { value: nil } %>
<% end %>
This will avoid the undefined method 'name' for User error.
 
    
    - 1,948
- 13
- 21
- 
                    2This worked for me: <%= f.input :create_key, input_html: {value: nil}, required: true, hint: "by invite only, see email for key" %> – codenoob Nov 09 '14 at 17:44
- 
                    1If working with a collection, use `selected` instead of `value` in order to avoid the `undefined method 'name' for Model` error – fkoessler Nov 02 '15 at 10:17
- 
                    " simple_form relies on using a model" thanks this is exactly what I was looking for :) – Olivier Girardot Aug 14 '21 at 14:45
You can also use fields outside the model within a form model, with simple_fields_for like this:
<%= simple_form_for @user do |f| %>
  <%= f.input :name %>
  <%= simple_fields_for :no_model_fields do |n| %>
    <%= n.input :other_field %>
  <% end %>
<% end %>
This is simple and practical solution, because you can create different kind of fields from different models or without using models
 
    
    - 1,250
- 2
- 14
- 23
You could also pass a :symbol instead of @object as argument for simple_form_for.
<%= simple_form_for :email, :url => '/post_email' do |f| %>
  <%= f.input :subject, :as => :string %>
<% end %>
Which would output:
<form method="post" class="simple_form email" action="/post_email" accept-charset="UTF-8">
  ...
  <input type="text" size="30" name="email[subject]" id="email_subject">
</form>
Please be aware of following draw-backs:
- You won't be able to take advantage of automatic model validation
- Need to explicitly define :urland the type of eachinput
 
    
    - 5,188
- 5
- 27
- 26
- 
                    3This option still uses a model under the covers. The symbol should match a model name, it will resolve to a model and create a new one and use it on every field, so the properties used in the form fields should actually exists in the model. – Miguel Madero Jul 02 '13 at 19:33
All of the methods above still leave you with form data nested inside of "user" or whatever symbol that you pass as the first argument. That's annoying.
To mimic simple_form's style/benefits, but remove the object/symbol dependency and the forced data nesting, you can create a partial.
HAML examples:
form view:
= form_tag("path/to/action", method: "POST") do
    = render "path/to/partial/field", type: "string", required: true, item: "first_name"
field partial:
- required_string = required ? "required" : ""
%div{class: "input #{type} #{required_string} #{item}"}
  %label{class: "#{type} #{required_string}", for: "#{item}"}
    - if required
      %abbr{title: "required"}
        *
    = t("application.#{item}")
  %input{name: "#{item}",                                                     |
    placeholder: t("application.#{item}"),                                    |
    type: "#{type}",                                                          |
    required: required,                                                       |
    "aria-required" => "#{required}" }
 
    
    - 4,770
- 2
- 18
- 15
In the case that you want to add a field that is not part of your model in your form, so that you don't want to read attributes, simple_form propose to use what they call a fake input in their wiki.
String Input
app/inputs/fake_input.rb:
class FakeInput < SimpleForm::Inputs::StringInput
  # This method only create a basic input without reading any value from object
  def input(wrapper_options = nil)
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    template.text_field_tag(attribute_name, nil, merged_input_options)
  end
end
Then you can do <%= f.input :thing, as: :fake %>
Boolean Input
app/inputs/fake_checkbox_input.rb:
class FakeCheckboxInput < SimpleForm::Inputs::StringInput
  # This method only create a basic input without reading any value from object
  def input(wrapper_options = nil)
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    tag_name = "#{@builder.object_name}[#{attribute_name}]"
    template.check_box_tag(tag_name, options['value'] || 1, options['checked'], merged_input_options)
  end
end
Then you can do <%= form.input :remove_avatar, as: :fake_checkbox, wrapper: :vertical_boolean %>
Select
app/inputs/fake_select_input.rb:
class FakeSelectInput < SimpleForm::Inputs::CollectionSelectInput
  def input(wrapper_options = nil)
    label_method, value_method = detect_collection_methods
    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options).merge(input_options.slice(:multiple, :include_blank, :disabled, :prompt))
    template.select_tag(
      attribute_name, 
      template.options_from_collection_for_select(collection, value_method, label_method, selected: input_options[:selected], disabled: input_options[:disabled]), 
      merged_input_options
    )
  end
end
Then you can do <%= f.input :thing, as: :fake_select, collection: my_collection, selected: params[:thing] %>
 
    
    - 428
- 4
- 10
 
    