Learn Ruby on Rails Book

Using bang method

In most of our applications we create sample data for development environment.

1User.create(name: "John Smity", role: "admin")

The problem with this approach is that if for any reason User.create fails then it will fail silently. This code will not raise any exception. It means rest of the processing will continue, and we will see something else failing at an unexpected place.

In this case we are populating sample data, so we expect all the validations to pass. If for any reason validation is not correct then it is best to fail loudly. In other words, fail with an exception. That can be done using "bang" version.

1User.create!(name: "John Smith", role: "admin")

Sometimes we need to process jobs in the background. In those cases also we should use bang version because if an update or create fails then we want to raise an exception and not just ignore the failure.

If user has submitted a form, and the validation fails then we should not be using bang version because if the create or update fails then we can ask the user to correct the problem.

Not using bang version

For example in this case not using bang method is appropriate.

1def create
2  @task = Task.new(task_params)
3  if @task.save
4    render status: :ok, json: { notice: 'Task was successfully created' }
5  else
6    errors = @task.errors.full_messages
7    render status: :unprocessable_entity, json: { errors: errors  }
8  end
9rescue ActiveRecord::RecordNotUnique => e
10  render status: :unprocessable_entity, json: { errors: e.message }