Giter Club home page Giter Club logo

rails-validations-errors's Introduction

#Error-Handling & Validations

Why is this important?

This workshop is important because:

Error-handling is a critical part of web development. One one hand developers need to ensure their applications validate input and raise errors appropriately. On the other hand it is also important design a good user experience for when these errors occur.

What are the objectives?

After this workshop, developers will be able to:

  • Use built-in ActiveRecord validation methods to validate database entries.
  • Display errors in the view using Rails flash messages.
  • Set breakpoints to check your assumptions

Where should we be now?

Before this workshop, developers should already be able to:

  • Construct a basic Rails application

##Error Handling

The best error-handling strategy is a combination of both client-side and server-side validations.

Client-side validations ensure a good user experience by providing real-time, inline feedback on the user input. Server-side validations are essential for maintaining database integrity, especially if the client-side validations are ever compromised or purposely circumvented.

Today for server-side validations in Rails, we will be using Active Record Validations. And for our client-side validations we will be building them with html5 attributes. Data form validation MDN

##Airplane App

For the purposes of this workshop there is a Rails app, airplane-app inside the repo that demonstrates the examples below.

The application was generated with: rails new airplane-app -T -B -d postgresql in order to prevent Rails from automatically creating tests (-T), prevent it from automatically bundling (-B), and set the database to postgres (-d postgresql).

Be sure to bundle, rails db:create db:migrate db:seed, and have postgres running before launching the application.

Model Validations

Validations provide security against invalid or harmful data entering into the database. ActiveRecord provides a convenient and easy set of built-in methods for validating model attributes, as well as the ability to define custom validator methods. An example of a built-in validation:

app/models/airplane.rb

class Airplane < ActiveRecord::Base
  validates :name, presence: true, uniqueness: true, length: {minimum: 6}
end

Here, the model is told to validate itself before saving to the database. The validates method takes the model as it's first argument and configuration options as the remaining arguments.

In rails console, if you try adding a new airplane to the database where a name is

  • not present
  • a duplicate
  • fewer than 6 characters

you'll get an error causing a ROLLBACK. Try, Airplane.create(name: "747"), which is a name of only three characters and see what happens.

What if you call Airplane.create!(name: "747")?

Alternatively, we can check any piece of data we are about to save with the .valid? method. So, instead if immediately calling.create. In that case, we can create a .new airplane instance in memory (without saving it to the database), then asking if it's .valid? before calling .save.

> airplane = Airplane.new(name: "747")
=> #<Airplane id: nil, name: "747", description: nil, created_at: nil, updated_at: nil>
> airplane.valid?
=> false

The .valid? method returns true if the new record passes the model validations and false if it fails any validations.

Moreover, we can call .errors.full_messages to returns an array of user-friendly error messages, which is very useful and will be helpful for our user experience later.

> airplane.errors.full_messages
=> ["Name is too short (minimum is 6 characters)"]

Let's look at how we can display the error messages to the user so they know what went wrong if their input doesn't pass our validations.

###Challenge: Duplicates (2 mins)

Get the airplane.errors.full_messages to return ["Name has already been taken"]

Displaying Errors to the User

In the airplane-app what currently happens when we try to submit invalid data to the database via the airplanes#new view?

As a user how are you supposed to know that something went wrong and what you are supposed to do about it?

In order to properly communicate what is happening behind the scenes, we can display flash messages to show them specific errors.

Error Handling in Views: Flash Messages

Rails comes with a flash hash, which stores a set of key/value pairs. We'll set a key-value pair on the flash hash in the controller to be rendered later in the view.

Because we're trying to display an error message we get back from Active Record we can store the error message in the flash.

flash[:error] = airplane.errors.full_messages

Add the above line into airplane#create action, if the airplane isn't saved correctly and before the :new view is rendered again.

app/controllers/airplanes_controller.rb

  def create
    @airplane = Airplane.new(airplane_params)
    if @airplane.save
      redirect_to @airplane
    else
      flash[:error] = airplane.errors.full_messages.join(" ")
      render :new
    end
  end

Just one last step! We've sent flash to the view, but we haven't rendered it yet. Let's do that in our application.html.erb layout, so we can render flash messages in every view:

app/views/layouts/application.html.erb

<% flash.each do |name, msg| %>
<div><%= msg %></div>
<% end %>

<%= yield %>

Note: run rails notes for further guidance on where to add the above lines of code.

Stretch Challenges and Debugging

Lastly there will be errors that crash your application that you need to catch and debug before they do so. This will require setting a break point in order for you to stop execution of the code and check your assumptions in a specific context. Let's discuss the preferred method to do so.

By default, Rails comes with the gem byebug loaded into the development & test environments. Anywhere in the code you can call byebug, which will set a breakpoint.

Set a breakpoint in airplanes#index, hit it. Can we add a query string to the url and inspect the params?

###Binding.pry

This is great, but wouldn't it be so much better if we had a colorful, well indented console to work in?

Let's swap out the gem byebug with pry-byebug and rebundle. Now we set breakpoints with binding.pry instead of debugger.

Gemfile

group :development, :test do

  # pry debugger
  gem 'pry-byebug'

  # Fake data
  gem 'ffaker'

end

Try accessing the query string in the url again, this time using binding.pry.

###Client-side Console

On a side note, note that anytime the application runs into an error, it loads up a console in the browser that interacts with byebug from the front-end via the gem web-console.

rails console

Additionally we can load up the console manually by invoking <% console %> somewhere in a view; generally, at the bottom of application.html.erb.

###Challenge

Render a variable @great_quote onto the view but do not set it explicitly in the controller. Instead use binding.pry to hit breakpoint, set @great_quote to something nice, continue, then see it rendered to the page.

More Challenges

We've just covered how to:

  • Implement validations
  • Query Active Record for validation errors
  • Handle errors appropriately
  • Display errors to the user
  • Set breakpoints in Rails

Resources

rails-validations-errors's People

Contributors

ilias-t avatar mattlaguardia avatar bgveenstra avatar

Watchers

James Cloos avatar Sherie avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.