When building forms in Rails, we often need to add custom behavior or default styles to form fields. While Rails provides a flexible FormBuilder through form_for
and form_with
, there are times when you want to streamline repetitive tasks, such as adding CSS classes to every form input. This is where creating a custom FormBuilder
comes in handy.
In this blog post, we’ll explore how to create a CustomFormBuilder
that automatically applies a CSS class to form fields, ensuring consistent styling without redundant code. We’ll also see how to implement it using form_for
.
Why Use a Custom FormBuilder?
A FormBuilder
in Rails helps generate form elements like text fields, password fields, and submit buttons, all tied to a specific model. The default FormBuilder
works well, but when your application requires custom logic—like always applying a certain CSS class or adding default options—you can extend it by creating a custom form builder.
This approach keeps your code DRY (Don’t Repeat Yourself) and ensures that all forms follow the same design patterns.
Creating a Custom FormBuilder
Let’s create a simple CustomFormBuilder
that adds the Bootstrap class form-control
to all text and password fields automatically.
First, create the CustomFormBuilder
class in app/helpers/custom_form_builder.rb
:
1
2
3
4
5
6
7
8
9
10
11
12
13
class CustomFormBuilder < ActionView::Helpers::FormBuilder
# Automatically adds the Bootstrap class 'form-control' to text fields
def text_field(method, options = {})
options[:class] = "form-control #{options[:class]}"
super(method, options)
end
# Automatically adds the Bootstrap class 'form-control' to password fields
def password_field(method, options = {})
options[:class] = "form-control #{options[:class]}"
super(method, options)
end
end
In this example, we’ve overridden the text_field
and password_field
methods. Each method adds the form-control
class to the input’s class
attribute and then calls super
to invoke the original method from the parent class (FormBuilder
). This way, our custom logic is layered on top of the default behavior.
Using the CustomFormBuilder in Views
Once the CustomFormBuilder
is defined, you can use it in your views with form_for
. Here’s an example:
1
2
3
4
5
6
7
8
9
10
= form_for @user, builder: CustomFormBuilder do |f|
.form-group
= f.label :username
= f.text_field :username
.form-group
= f.label :password
= f.password_field :password
= f.submit "Sign In", class: "btn btn-primary"
In this example:
- We use
form_for @user
and pass theCustomFormBuilder
as thebuilder
option. - The
CustomFormBuilder
applies theform-control
class to thetext_field
andpassword_field
, ensuring that Bootstrap’s styles are used automatically. - The
submit
button is styled manually, but you could also extend thesubmit
method inCustomFormBuilder
to apply styles globally.
Why Choose form_for over form_with?
Both form_for
and form_with
can accept custom form builders. While form_with
is the newer syntax introduced in Rails 5.1, some developers still prefer form_for
for its explicitness when handling model objects. In this example, we used form_for
for simplicity and clarity, but you can easily adapt this to form_with
if preferred.
Creating a custom FormBuilder
in Rails allows you to encapsulate repetitive form behaviors, such as adding default classes or handling specific input types in a consistent manner. By doing this, you maintain cleaner views, reduce duplication, and ensure that your forms remain consistent across your application.