Rails form helpers making your life easier!

Today we will talk about a really nice implementation in rails!
As always, we will talk about it because we needed to use it in one of our issues. We are talking about the: reject_if.
The reject_if is used together with the active record nested attributes. These two can make your life easier when you don’t want to save objects that do not obey some rules. First, let’s talk a little bit about the accepts nested attributes.
The accepts_nested_attributes_for is the easier way to save changes in models that are associated with other models.
For example, let’s suppose that you have an user model and a form to update user data. Inside this form, you would like to fill data about address, however the address is not an attribute of your user, but other model associated with your user model. In order to do that, you just have to add in your user model the accepts_nested_attributes_for. Like this:
class User < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
endAnd then, in your form view, you add a fields_for the address. Like this:
<%= form_for @user do |user_form| %>
name: <%= user_form.text_field :name %><%= fields_for :address, @user.address do |address_fields| %>
street : <%= address_fields.text_field :street %>
city: <%= address_fields.text_field :city %>
postal code : <%= address_fields.text_field :postal_code %>
<% end %><%= user_form.submit %>
<% end %>
This way, you can update the address for user using the user form. In other words, the accepts_nested_attributes_for enables you to update attributes for address model through the user model.
In the user controller, the params will be like this:
params = { user: { name: 'Jack', address_attributes: { street: 'street 4', city: 'new york' , postal_code: '15485156' } } }This is already nice! but besides that, there are some options for this accepts_nested_attributes_for helper. One of them is the reject_if.
The reject_if it is used when you want to discard an object that does not filled some criteria. Using it, you will not save (you will ignore) a specific object if it is not filled like you want.
For example, in the case of the user’s address, if the user has not filled the postal code, you do not want to save his address. Maybe in your case the address is not an mandatory data to have, but when filled you just want to save those that have the postal code.
Your problem now is: JUST if the user fill the postal code you want to save address, if he doesn’t you want to discard the address data.
For this purpose you can do something like this:
class User < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address, reject_if: :without_postal_codedef without_postal_code(attributes)
attributes['postal_code'].blank?
end
end
Simple like that!
Now, when you call user.save in your user controller, you don’t need to worry about verify if the postal code in user address is filled. The active record already did all the hard job!
In order to know better about the details of using this, or if you want to know other nice helpers associated with accepts_nested_attributes_for, you can visit these pages:
- https://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for
- http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Happy coding!
