© Brady Somerville, Adam Gamble, Cloves Carneiro Jr and Rida Al Barazi 2020
B. Somerville et al.Beginning Rails 6https://doi.org/10.1007/978-1-4842-5716-6_3

3. Getting Something Running

Brady Somerville1 , Adam Gamble2, Cloves Carneiro Jr.3 and Rida Al Barazi4
(1)
Bowling Green, KY, USA
(2)
Gardendale, AL, USA
(3)
Hollywood, FL, USA
(4)
FONTHILL, ON, Canada
 

The best way to learn a programming language or a web framework is to dig in and write some code. After reading the first two chapters, you should have a good understanding of the Rails landscape. Chapter 4 will lead you through the Ruby language, but first let’s write a little code to whet your appetite. This chapter builds a foundation and will get you excited by walking you through the construction of a basic application. You will learn how to create a database and how to connect it to Rails, as well as how to use a web interface to get data in and out of the application.

You will receive a lot of information in this chapter, but it shouldn’t be more than you can absorb. The goal is to demonstrate, not to overwhelm. Rails makes it incredibly easy to get started, and that’s a feature this chapter highlights. There are a few places where Rails really shines, and getting something running is one of them. By the end of this chapter, you’ll have a working web application to play with, explore, and learn from. You’ll build on this application throughout the rest of the book, adding features and refining functionality.

An Overview of the Project

This chapter will walk you through building a simple blog application that lets you create and publish articles, like WordPress or Blogger. The first iteration focuses on the basics: creating and editing articles.

Before you start coding, let’s sketch a brief summary of the goals and flow of the application at a very high level. The idea isn’t to focus on the nitty-gritty, but instead to concentrate on the general case.

Your application will have two kinds of users: those who post and publish articles and those who wish to comment on existing articles. In some cases, people will play both roles. Not all users will need to create an account by registering on the site. It will also be nice if people can notify their friends about interesting articles using a feature that sends a friendly email notification to interested parties.

You will add some of these features in later chapters. Other application requirements will likely come up as you continue, but these are enough to get started. In the real world, specifications evolve as we learn how real users interact with our web applications. Don’t let this frustrate you or surprise you—that’s what the Agile methodology of software development recognizes and celebrates. Rails doesn’t penalize you for making changes to an application that’s under construction, so you can engage in an iterative style of development, adding and incrementing functionality as you go.

You start with what matters most: articles. You may wonder why you don’t begin with users. After all, without users, who will post the articles? If you think about it, without articles, what could users do? Articles are the epicenter of the application, so it makes the most sense to start there and work out the details as you go. Ready? Let’s get started!

Creating the Blog Application

As you saw in Chapter 2, the first step is to create a new Rails application. You could come up with a fancy name, but let’s keep it simple and call the application blog. It’s not going to win any awards for creativity, but it works.

To begin, from the command line, go to the directory where you want to place your new application; then, issue the rails command to generate the application skeleton and base files:
$ rails new blog
  create
  create  README.md
  create  Rakefile
  create  .ruby-version
  create  config.ru
  create  .gitignore
  create  Gemfile
...
As you recall from the example in Chapter 2, the rails command takes as an argument the name of the project you want to create and generates a directory of the same name that contains all the support files. In this case, it creates a subdirectory called blog in the current working directory. Change into the blog directory and get oriented. Figure 3-1 shows the directory structure.
../images/314622_4_En_3_Chapter/314622_4_En_3_Fig1_HTML.jpg
Figure 3-1

The Rails directory structure

You’ll quickly get used to the Rails directory structure, because all Rails applications follow this standard. This is another benefit of conventions: you always know where to locate files if you have to work on a Rails project that was developed by someone else. Table 3-1 briefly explains the directory structure.
Table 3-1

Rails Directory Structure

Folder/File

Description

app

All the components of your application.

bin

Executables to support Rails.

config

Configuration files for all of the components of your application.

db

Files related to the database you’re using and a folder for migrations.

lib

Libraries that may be used in your application.

log

Log files that your application may require.

node_modules

External javascript dependencies.

public

Static assets served by your application, such as images, JavaScript, and CSS files.

storage

Contains uploaded files when using Active Storage’s disk service.

test

Directory containing unit tests for your application.

tmp

Contains temporary files supporting your application.

vendor

External libraries, such as gems and plug-ins, that your application bundles.

.browserslistrc

Configuration file which declares what types of browsers your frontend (JS/CSS) tools should try to support.

.gitignore

Contains patterns of files/directories to ignore when saving changes to version control.

.ruby-version

Declares which version of Ruby to use with this Rails project.

babel.config.js

Configures babel so you can write javascript code with new features and syntax that can still work on older browsers.

config.ru

A file used by rack servers to start the application.

Gemfile

Used by the bundler gem to keep a list of gems used in your application.

Gemfile.lock

Canonical resource of what gems should be installed.

package.json

Declares javascript dependencies and configuration.

postcss.config.js

Config for PostCSS (a tool that lets you process CSS with javascript).

Rakefile

Lists available for tasks used by Rake.

README.md

Human-readable file generated to describe an application.

yarn.lock

Canonical resource of which javascript dependencies should be installed (like Gemfile.lock, but for javascript!).

Your first stop is the config directory. Of the little configuration there is to do in a Rails application, most of it takes place in this aptly named location. To get an idea of what Rails expects as far as databases go, open the config/database.yml file in your editor and take a peek. You should see something like the file shown in Listing 3-1 (comments are omitted here).
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000
development:
  <<: *default
  database: db/development.sqlite3
test:
  <<: *default
  database: db/test.sqlite3
production:
  <<: *default
  database: db/production.sqlite3
Listing 3-1

The config/database.yml File

The first thing you should notice is the different sections: development, test, and production. Rails understands the concept of environments and assumes you’re using a different database for each environment. Therefore, each has its own database connection settings, and different connection parameters are used automatically. Rails applications run in development mode by default, so you really only need to worry about the development section at this point. Still, other than the database names (db/*.sqlite3), there should be little difference between the connection parameters for each environment.

This example uses the default SQLite database because it’s easy to use and set up. However, you can use the database management system of your choice by passing the –d or --database= option to the “rails new” command with one of the following options as per your preference: mysql, oracle, postgresql, sqlite3, sqlserver, or other supported database servers. (See “rails new --help” for a complete list.)

If you select a database other than SQLite, the rails command may prefill the database parameter based on the database server and project name: blog in this case. If you give your application a different name (say, a snazzy Web 2.0 name like blog.ilicio.us *beta) with a database server such as MySQL, you’ll see something different here. It doesn’t matter what you name your databases, as long as database.yml references the correct one for each environment. Let’s stick with the convention and create the databases using the default names.

What is YAML?

The .yml extension refers to a YAML file. YAML (a recursive acronym that stands for “YAML Ain’t Markup Language”) is a special language for expressing objects in plain text. Rails can work with YAML natively and can turn what looks like plain text into Ruby objects that it can understand.

YAML is whitespace sensitive: it uses spaces (not tabs) to convey structure and meaning. Make sure your editor knows the difference between tabs and spaces, and be sure that when you’re editing YAML files, you use only spaces.

Creating the Project Databases

You may think that to create a new database, you’ll use your favorite database administration tool. However, because you already told Rails the database connection details, you can now run a Rails command that talks to the database and issues all the necessary commands to set up the databases. Jump to the command prompt and type:
$ cd blog
$ rails db:create

When using SQLite, you aren’t forced to create the database, because a new database file is automatically created if one doesn’t exist; but it will come in handy when you try a different database engine. You also may see some messages like db/development.sqlite3 already exists. Don’t be afraid—this is an indication that an SQLite file was found. If you see that message, rest assured that your existing database was left untouched and no database file has been harmed.

Regardless of the database management system you select, you should notice that the databases you want to use are created. This is another case in which Rails removes some complexity from your mind and helps you focus on your application.

Note

Depending on how your environment is set up, you may not need to specify the username, password, and other options in your config/databases.yml file to create the database.

Although you’re only concerned with the development environment at this time, it doesn’t hurt to create the other databases while you’re at it. Go ahead and create two more databases, one each for the test and production environments:
$ rails db:create:all
Rails provides an easy way to interact directly with the database via its command-line interface. You can confirm the creation of the database by using the rails dbconsole program to interact with your development database:
$ rails dbconsole
SQLite version 3.29.0 2019-07-10 17:32:03
Enter ".help" for usage hints.
sqlite> .databases
main: /path/to/your/blog/db/development.sqlite3
sqlite> .exit
At this point, you can issue any number of SQL (Structured Query Language) statements and look at the tables and records that eventually will be in your application. (If you aren’t familiar with SQL, you can learn more about it in Appendix B.) When you’re finished with the SQLite console, type the .exit command to go back to your regular prompt. You can test to see if your connection is working by running the following command:
$ rails db:migrate
If nothing exceptional is returned, congratulations! Rails can connect to your database. However, if you’re using a database engine other than SQLite and you may see something like this
rake aborted!
Access denied for user 'root'@'localhost' (using password: NO)

then you need to adjust your connection settings. If you’re having problems, make sure the database exists and that you’ve entered the correct username and password in the config/database.yml configuration file.

Creating the Article Model

Now that you can connect to the database, this section will explain how you create a model. Remember that models in Rails usually correspond to database table names. Because you want to model articles, let’s create a model named Article. By convention, model names are camel-cased singular and correspond to lowercased plural table names. So an Article model expects a table named articles; a Person model expects a table named people.

Note

Camel case means that each word begins with a capital letter and is written without spaces. For instance, a class that described blog images would be written as BlogImage. Refer to http://en.wikipedia.org/wiki/CamelCase for more information.

Rails is smart enough to use the correct plural name for most common words; it doesn’t try to create a persons table.

Like most things in Rails, models have their own generator script that makes it easier to get started. The generator automatically creates a new model file in the app/models directory and also creates a bunch of other files. Among these are a unit test (for testing your model’s functionality, as discussed in Chapter 16) and a database migration. A database migration contains instructions for modifying the database table and columns. Whenever you generate a new model, a migration is created along with it.

Note

If you want to skip generation of the migration when generating a new model, you can pass the --no-migration argument to the generator. This may be useful if you’re creating a model for an existing database or table.

To see the generator’s usage information, run it without arguments:
$ rails generate model
Usage:
  rails generate model NAME [field[:type][:index] field[:type][:index]] [options]
...

As you can see from the usage banner, the generator takes a model name as its argument and an optional list of fields. The model name may be given in camel-cased or snake-cased format, and options can be provided if you want to automatically populate the resulting migration with column information.

Note

Snake-cased words are written in all lowercase with underscores replacing spaces, for instance, blog_image. For more information, visit http://en.wikipedia.org/wiki/Snake_case.

Let’s run the generator now to create the first model, Article:
$ rails generate model Article
  invoke  active_record
  create  db/migrate/20191219235126_create_articles.rb
  create  app/models/article.rb
  invoke  test_unit
  create  test/models/article_test.rb
  create  test/fixtures/articles.yml

If you look at the lines that start with create, you see that the generator has created an Article model, an Article test, an articles fixture (which is a textual representation of table data you can use for testing), and a migration named 20191219235126_create_articles.rb. From that, your model is generated.

Note

The first part of the migration file name is the timestamp when the file was generated. So the file on your computer will have a slightly different name.

Creating a Database Table

You need to create a table in the database. You could do this with a database administration tool or even manually using SQL, but Rails provides a much more efficient facility for table creation and maintenance called a migration. It’s called a migration because it allows you to evolve, or migrate, your schema over time. (If you’re not familiar with databases, tables, and SQL, consult Appendix B for the basics.)

Note

Schema is the term given to the properties that make up a table: the table’s name, its columns, and its column types, as well as any default values a column will have.

What’s the best part about migrations? You get to define your schema in pure Ruby. This is all part of the Rails philosophy that you should stick to one language when developing. It helps eliminate context switching and results in higher productivity.

As you can see from the output of the model generator, it created a new file in db/migrate called 20191219235126_create_articles.rb. As mentioned before, migrations are named with a numeric prefix, which is a number that represents the exact moment when the migration file was created. Because multiple developers can create migrations in a development team, this number helps uniquely identify this specific migration in a project.

Let’s open this file and take a peek. It’s shown in Listing 3-2.
class CreateArticles < ActiveRecord::Migration[6.0]
  def change
    create_table :articles do |t|
      t.timestamps
    end
  end
end
Listing 3-2

The db/migrate/20191219235126_create_articles.rb File

In its initially generated form, the migration is a blank canvas. But before you go any further, let’s note a few important items. First, notice the instance method: change. In previous versions of Rails, there would be an up and down class method, but now Rails is smart enough to figure it out based on the modifications you make in this method. You can roll back without ever writing a method that explicitly drops the table. Pretty slick, isn’t it?

Listing 3-3 has the details filled in for you. Even without ever having seen a migration before, you should be able to tell exactly what’s going on.
class CreateArticles < ActiveRecord::Migration[6.0]
  def change
    create_table :articles do |t|
      t.string      :title
      t.text         :body
      t.datetime :published_at
      t.timestamps
    end
  end
end
Listing 3-3

Completed db/migrate/20191219235126_create_articles.rb File

Let’s step through the code. First, you use the create_table method, giving it the name of the table you want to create. Inside the code block, the string, text, and datetime methods each create a column of the said type named after the parameter; for example, t.string :title creates a field named title with the type string. The timestamps method, in the t.timestamps call, is used to create a couple of fields called created_at and updated_at, which Rails sets to the date when the record is created and updated, respectively. (For a full description of the available method types you can create in your migrations, see https://api.rubyonrails.org/classes/ActiveRecord/Migration.html.)

On its own, this migration does nothing. Really, it’s just a plain old Ruby class. If you want it to do some work and create a table in the database for you, you need to run it. To run a migration, you use the built-in db:migrate Rails command that Rails provides.

From the command line, type the following to run the migration and create the articles table. This is the same command you used to test the database connection. You sort of hijack it for this test, knowing that it will attempt to connect to the database and thus prove whether the connection works. Because there were no existing migrations when you first ran it, it didn’t do anything. Now that you have your first migration, running it results in a table being created:
$ rails db:migrate
== 20191219235126 CreateArticles: migrating ===============================
-- create_table(:articles)
   -> 0.0028s
== 20191219235126 CreateArticles: migrated (0.0029s) ======================

Just as the output says, the migration created the articles table. If you try to run the migration again (go ahead, try it), nothing happens. That’s because Rails keeps track of all the migrations it runs in a database table, and in this case there’s nothing left to do. If for some reason you decide you need to roll back the migration, you can use the db:rollback task to roll back. Try it and you will notice that it dropped the articles table. Remember that we never wrote any code to drop the table, Rails just handled it for us. Imagine if you would have edited the database schema directly with a database management tool; if you wanted to roll back, you’d have to remember what it looked like before and exactly what you changed. This makes your life much easier. Okay, before we move on, don’t forget to run migrations again since we rolled back.

Generating a Controller

You’ve created a model and its supporting database table, so the next step is to work on the controller and view side of the application. Let’s create a controller named articles (remember controllers are plural and models are singular) to control the operation of the application’s articles functionality. Just as with models, Rails provides a generator that you can use to create controllers:
$ rails generate controller articles
  create  app/controllers/articles_controller.rb
  invoke  erb
  create    app/views/articles
  invoke  test_unit
  create    test/controllers/articles_controller_test.rb
  invoke  helper
  create    app/helpers/articles_helper.rb
  invoke    test_unit
  invoke  assets
  invoke    scss
  create      app/assets/stylesheets/articles.scss
The controller generator creates four files:
  • app/controllers/articles_controller.rb: The controller that is responsible for handling requests and responses for anything to do with articles.

  • test/controllers/articles_controller_test.rb: The class that contains all functional tests for the articles controller (Chapter 16 covers testing applications).

  • app/helpers/articles_helper.rb: The helper class in which you can add utility methods that can be used in your views (Chapters 7 and 8 cover helpers).

  • app/assets/stylesheets/articles.scss: This is a SASS (Syntactically Awesome Style Sheets) file where you can put style sheets for the associated views.

Note

SASS is a language that compiles into CSS. SASS extends CSS with enhanced syntax that helps developers organize their CSS and simplify their code. (See https://sass-lang.com/ for more info.) Rails supports SASS out of the box by precompiling it into CSS automatically via the Asset Pipeline.

The controller generator also creates an empty directory in app/views called articles. This is where you place the templates for the articles controller.

Up and Running with Scaffolding

One of the most talked-about features that has given a lot of exposure to Rails is its scaffolding capabilities. Scaffolding allows you to create a boilerplate-style set of actions and templates that makes it easy to manipulate data for a specific model. You generate scaffolding using the scaffold generator. You’re probably getting used to generators by now. Rails makes heavy use of them because they help automate repetitive tasks and generally remove the chances for errors when creating new files. Unlike you probably would, the generator won’t ever forget how to name a file; nor will it make a typo when creating a class. Let’s use the scaffold generator now and solve the mystery of how this works.

First, we need to remove the files we generated in the previous steps. Rather than having to find all the files we generated and delete them by hand, we can use the “rails db:rollback” and “rails destroy” commands to undo previous operations. Run the following commands:
$ rails destroy controller articles
$ rails db:rollback
$ rails destroy model Article
Now, we’ll run the following commands to generate scaffolding for our Article model, complete with controllers, views, and other files, and then to create the database table:
$ rails generate scaffold Article title:string body:text published_at:datetime
$ rails db:migrate
The scaffold provides methods and pages that allow you to insert, update, and delete records in your database. That’s all you need to generate a working scaffold of the Article model. Let’s fire up the web server and test it. Start your local web server from the command line (rails server), and browse to the articles controller in your browser:
http://localhost:3000/articles
You should see the results displayed in your browser, as shown in Figure 3-2.
../images/314622_4_En_3_Chapter/314622_4_En_3_Fig2_HTML.jpg
Figure 3-2

Articles scaffolding

Click the New Article link, and you’re taken to a screen where you can enter articles. Notice that the URL is http://localhost:3000/articles/new, which means you’re invoking the new action on the articles controller. Go ahead and add a few articles and generally play with the application. Figure 3-3 shows an example of an article entered on this screen.
../images/314622_4_En_3_Chapter/314622_4_En_3_Fig3_HTML.jpg
Figure 3-3

Adding an article

Notice that every time you add an article, you’re redirected back to the show action, where you see the details of the article you just created. You can click “Back” to go the index action, where you see all of your articles listed. You can edit them, delete them, or create new ones. You’ve got to admit, Rails gives you a lot of functionality for free.

Speed is the key benefit here. The scaffold generator allows you to quickly get something running, which is a great way to test your assumptions.

Caution

Scaffolding comes with an important disclaimer. You shouldn’t use it in production. It exists to help you do exactly what you just did: get something running. By its definition, it’s a temporary or unfinished product.

Adding More Fields

Now that you can see the model represented in the browser, let’s add some more fields to make it a little more interesting. Whenever you need to add or modify database fields, you should do so using a migration. In this case, let’s add the excerpt and location fields to the articles table.

You didn’t need to generate the last migration (the one you used to create the articles table), because the model generator took care of that for you. This time around, you can use the migration generator. It works just like the model and controller generators, which you’ve seen in action. All you need to do is give the migration generator a descriptive name for the transformation:
$ rails generate migration add_excerpt_and_location_to_articles
excerpt:string location:string
  invoke  active_record
  create    db/migrate/20191220013103_add_excerpt_and_location_to_articles.rb
As you’ve already seen, the generator creates a migration class in db/migrate prefixed by a number identifying when the migration was created. If you open the 20191220013103_add_excerpt_and_location_to_articles.rb file, you see the migration class with the code shown in Listing 3-4. As with the model generator, which prefilled the migration to some extent, passing field names and types as options to the migration generator prefills the generated class for you as long as you refer to the correct table name at the end of the migration name—in this case, to_articles.
class AddExcerptAndLocationToArticles < ActiveRecord::Migration[6.0]
  def change
    add_column :articles, :excerpt, :string
    add_column :articles, :location, :string
  end
end
Listing 3-4

The db/migrate/20191220013103_add_excerpt_and_location_to_articles.rb File

Looking at the add_column method, the first argument is the table name (articles), the second is the field name, and the third is the field type. Remember that the change method knows how to migrate up or down, so if in the unlikely event you want to remove these columns, Rails will know how.

With this new migration in place, use the following Rails command to apply it and make the changes to the database:
$ rails db:migrate
== 20191220013103 AddExcerptAndLocationToArticles: migrating ===========
-- add_column(:articles, :excerpt, :string)
   -> 0.0030s
-- add_column(:articles, :location, :string)
   -> 0.0017s
== 20191220013103 AddExcerptAndLocationToArticles: migrated (0.0052s) =====

If all goes according to plan, the articles table now has two new fields. You could edit the view templates in the app/views/articles folder to add form elements for the new fields, but instead let’s call the generator again (you’ll learn about views in Chapter 7):

First, we need to remove a few files again, so that the generator won’t refuse to run:
  • app/models/article.rb

  • app/controllers/articles_controller.rb

  • app/helpers/articles_helper.rb

And now, we can rerun the scaffold generator with our new options:
$ rails generate scaffold Article title:string location:string excerpt:string
body:text published_at:datetime --no-migration
Press Y when asked if you want to overwrite some files, and you’re finished, as you can see in Figure 3-4.
../images/314622_4_En_3_Chapter/314622_4_En_3_Fig4_HTML.jpg
Figure 3-4

Additional fields added to the new article form

This exposes one of the issues of this type of scaffolding: when you generate new versions of the scaffold files, you run the risk of overwriting custom changes you may have made. We’re doing it this way as an illustration, but you wouldn’t normally do this.

Adding Validations

You may wonder what happens if you try to save a new article without giving it any information. Try doing that: Rails doesn’t care. Actually, it’s the Article model that doesn’t care. This is because in Rails, the rules for data integrity (such as required fields) are the responsibility of the model.

To add basic validation for required fields, open the Article model in app/models/article.rb and add the validation method shown in Listing 3-5 inside the class body.
class Article < ApplicationRecord
  validates :title, :body, presence: true
end
Listing 3-5

Validation Added to the app/models/article.rb File

Save the file, and try creating an empty article again. Instead of saving the record, Rails displays a formatted error message, as shown in Figure 3-5.
../images/314622_4_En_3_Chapter/314622_4_En_3_Fig5_HTML.jpg
Figure 3-5

Error messages for an article

If you’ve done any web development before, you know that validating fields is a major nuisance. Thankfully, Rails makes it easy.

Note

Notice that you don’t need to restart the web server when you make changes to your project files in the app/ directory. This is a convenience provided by Rails when running in development mode.

Chapter 6 goes through all the specifics of model validations. For now, you’re using only the most primitive methods of protecting your data. It shouldn’t surprise you that Active Record is capable of much more involved validations, such as making sure a numeric value is entered, validating that data are in the correct format using regular expressions, and ensuring unique values, among other checks.

Note

Regular expressions (regex for short) are expressions that describe patterns in strings. Like most programming languages, Ruby has built-in support for regular expressions.

Generated Files

Now that you’ve seen the pages in action, let’s look at the articles controller again. As you can see in Listing 3-6, the controller is now chock-full of actions. There’s one for each of index, show, new, create, edit, update, and destroy—the basic CRUD actions.
class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]
  # GET /articles
  # GET /articles.json
  def index
    @articles = Article.all
  end
  # GET /articles/1
  # GET /articles/1.json
  def show
  end
  # GET /articles/new
  def new
    @article = Article.new
  end
  # GET /articles/1/edit
  def edit
  end
  # POST /articles
  # POST /articles.json
  def create
    @article = Article.new(article_params)
    respond_to do |format|
      if @article.save
        format.html { redirect_to @article, notice: 'Article was successfully created.' }
        format.json { render :show, status: :created, location: @article }
      else
        format.html { render :new }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end
  # PATCH/PUT /articles/1
  # PATCH/PUT /articles/1.json
  def update
    respond_to do |format|
      if @article.update(article_params)
        format.html { redirect_to @article, notice: 'Article was successfully updated.' }
        format.json { render :show, status: :ok, location: @article }
      else
        format.html { render :edit }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end
  # DELETE /articles/1
  # DELETE /articles/1.json
  def destroy
    @article.destroy
    respond_to do |format|
      format.html { redirect_to articles_url, notice: 'Article was successfully destroyed.' }
      format.json { head :no_content }
    end
  end
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_article
      @article = Article.find(params[:id])
    end
    # Only allow a list of trusted parameters through.
    def article_params
      params.require(:article).permit(:title, :location, :excerpt, :body, :published_at)
    end
end
Listing 3-6

The app/controllers/articles_controller.rb

As you did in this chapter, after you’ve generated scaffolding, if you change your model, you have to regenerate it if you want your application to follow suit. Most of the time, however, you make the changes by hand and have a variation of the default scaffold.

It’s important to realize why scaffolding exists and to be aware of its limitations. As you’ve just seen, scaffolding helps when you need to get something running quickly to test your assumptions. It doesn’t take you very far in the real world, and eventually you end up replacing most (if not all) of it.

Explore the generated code and see if you can figure out how it hangs together. Don’t worry if you can’t understand all of it—the chapters that follow will discuss it in depth. With everything you know about Rails already, you should be able to piece together most of it.

Try changing a few things to see what happens. If you inadvertently break something, you can always run the scaffolding generator again to revert to the original. Can you see how the views in app/views/articles are related to the actions? What about the response messages, like Article was successfully created? What happens when you change them? See if you can find where the error messages for failed validations are rendered. If you remove the message, does the record still get saved? You can learn a lot by exploring, so take as much time as you need.

Summary

This chapter started by outlining the basics of the sample application. Then, you rolled up your sleeves and created a database and configuration files. Based on the goals of the application, you began by creating the tables necessary to run the core of your Article model and got a first look at the simplicity and flexibility that migrations give the development process. The scaffolding allowed you to test your assumptions about the model and table you created by getting a firsthand look at it in action. You also took a first crack at adding in validations that ensure you maintain the integrity of your data. The chapters that follow investigate these concepts in depth, starting with the first part of the MVC principle: models.