Is it possible to use Simple Form (by: Plataformatec) without a model?
5 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>
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.
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
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
:url
and the type of eachinput
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}" }