Posted about 7 years ago. Visible to the public.

Ruby on Rails basics [4d]

Rails is our web framework.

Goals

  • Be able to write a simple Rails application.
  • Understand how Rails talks to the database (ActiveRecord)
    • What is a model?
    • How are records retrieved and saved?
    • Validations
    • Migrations
    • belongs_to, has_many, has_many :through
  • Gain an understanding of the structure of a basic Rails app
    • Routes
    • Controllers
      • Generate a controller using Rails scaffolding
      • Write your own controller
    • Views
      • using ERB
    • Models
    • Helpers
  • Learn how to do CRUD ("Create", "Read", "Update", "Destroy")
    • How to show a list of existing database records
    • How to build a user interface to show and update database records

Resources

Exercises

Rails tutorial

Find The Ruby on Rails Tutorial in our library. It should be the 6th edition that works with Rails 6.1.

Work through the following chapters and skip the rest. Also skip deployment to Heroku everywhere.

Copy
1 From zero to deploy Introduction 1.1 Up and running 1.2 The first application 2 A toy app All sections 3 Mostly static pages All sections 5 Filling in the layout All sections 6 Modeling users All sections 7 Sign up Introduction 7.1 Showing users 7.2 Signup form 7.3 Unsuccessful signups 7.4 Successful signups 7.6 Conclusion 8 Basic login All chapters 13 User microposts All chapters

For each chapter:

  • You should do all the programming exercises.
  • You can skip the testing exercises. We are going to learn testing in a later card. We're also using different testing frameworks and different types of tests than the tutorial.

We will also be using a different development environment than the book suggests. Deviate from the following instructions:

  • We are managing Ruby versions using rbenv, not RVM. rbenv is already installed on your PC.
  • The Ruby version used by the tutorial (2.7) is already installed on your PC. You can check with ruby -v.
  • Node.js is already installed on your PC. Check with node -v.
  • Yarn is already installed on your PC. Check with yarn -v.
  • We will not use a cloud-based editor like "Cloud9". Instead we will develop on our local machine and use a local IDE like RubyMine. Skip any instructions for cloud IDEs.
  • We will not upload our code to GitHub. Push your code to our private GitLab instance instead.
  • We are developing on Linux. Skip all sections specific to MacOS or Windows.

Movie database

We want to take what learned from the tutorial and apply it to our own app. In this exercise we will write a Rails app that manages a list of movies and a list of actors. We will call this app "MovieDB" in subsequent cards.

Your MovieDB should deliver the following requirements:

  • There should be a full CRUD Archive interface for movies and actors.
  • Movies have a year and name.
  • Actors just have a name.
  • Movies can have multiple actors (and hence an actor can star in multiple movies).
  • The user should be able to create a new movie/actor association from a movie's show view.
  • You only need very basic styling of the UI. We will learn CSS in a later card.
  • Your application layout should have a navigation bar to switch between sections (movies, actors).

For our MovieDB we will use Rails 7 without Turbolinks. You should already have forked your own copy at the previous card

Hint

  • Use a join model Archive like Role or Casting to associate actors with the movies they star in. A movie's show view should link to associated actors. An actor's show view should link to associated movies.
  • We recommend to build the views from scratch, without scaffolding. If you do use scaffolding, you must understand every line of the generated code. Also delete any generated code that is not required for your application.

Beautiful controller pattern

Refactor your MovieDB controllers to the pattern in our book Growing Rails Applications in Practice Archive (chapter "Beautiful Controllers").

The book is in our library.

Understand how forms pass values to your model

In this exercise we take a closer look at how the HTML forms produced by Rails helpers, and how user input in those forms is sent over the wire and saved to your database.

Tip

We are not going to keep changes from this exercise. Before you start, make sure all changes from previous exercises and commited and pushed. We will discard any changes at the end of this exercise.

Take a look at your view to create a new movie, app/views/movies/new.erb. It will look something like this:

Copy
<%= form_for @movie do |form| %> <%= form.text_field :title %> <%= form.text_field :year %> <%= form.submit %> <% end %>

Your actual view will be longer. For the sake of this example we only look at a minimal subset.

Now go to http://localhost:3000/movies/new to access that view. Right-click into your form and select Inspect. You should see the HTML generated by your view. It will look something like this:

Copy
<form action="/movies"> <input type="text" name="movie[title]"> <input type="text" name="movie[year]"> <input type="submit" name="commit" value="Save movie"></button> </form>

Again your actual HTML will be longer.

Note the peculiar name attributes of the inputs, e.g. movie[title]. This name was chosen automatically by the form.text_field helper, and it will be helpful later.

How form data is transferred and parsed

Now open the Network tab in your developer console (CTRL+Shift+I in Chrome).

Fill out the movie. Use the title Sunshine and the year 2007. Submit the form.

In the network tab you will see the HTTP request to save the movie. Select the request from the list and go to the sub-tab Payload. You should see your request's payload as a list of key/value pairs:

Copy
movie[title] Sunshine movie[year] 2007 commit Save movie

Now change your MoviesController#create method so it prints out the params that Rails sees. For this we comment out the code that was creating the movie and render the params object:

Copy
def create # @movie = Movie.new # @movie.attributes = params[:movie] # if @movie.save # redirect_to @movie # else # render 'new' # end render plain: params.inspect end

Note that #inspect returns a human-readable representation of an object. All Ruby objects implement this.

Submit the new movie form again and you should see something like this:

Copy
{ 'controller' => 'movies', 'action_name' => 'create', 'movie' => { 'title' => 'Sunshine', 'year' => '2007' }, 'commit' => 'Save movie' }

Note how Rails has used the square brackets in the payload keys to group all movie attributes into one sub-hash, params['movie'].

Let's take a look at only the movie-related attributes:

Copy
def create # @movie = Movie.new # @movie.attributes = params[:movie] # if @movie.save # redirect_to @movie # else # render 'new' # end render plain: params[:movie].inspect end

Note that we can use either params[:movie] (symbol key) or params['movie'] (string key) and get the same value. This is a peculiarity of the params hash, other Ruby hashes don't share this behavior.

Submit the new movie form again and you should see something like this:

Copy
{ 'title' => 'Sunshine', 'year' => '2007' }

How parsed params are assigned to a record

Restore the original implementation of MoviesController#create. It probably has a line like this somewhere:

Copy
@movie.attributes = params[:movie]

We now know that this expands to the following:

Copy
@movie.attributes = { 'title' => 'Sunshine', 'year' => '2007' }

And this is a shortcut to set individiual attributes in separate lines:

Copy
@movie.title = 'Sunshine' @movie.year = '2007'

Hopefully this clarifies how form values are assigned to your model records.

Clean-up

When you're done with this exercises, discard all changes:

Copy
git reset --hard

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for unsupported versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2).

Owner of this card:

Avatar
Henning Koch
Last edit:
2 months ago
by Maximilian Berger
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra Curriculum
This website uses short-lived cookies to improve usability.
Accept or learn more