Database and migration 2020
In this chapter, we'll see how Rails interacts with databases, and focus more on the architecture.
We did run the scaffold generator in A quickest way of building a blog with posts and comments. If we generate models as well, it creates a database migration, and these migration files are in our Rails application. So, each time we run the scaffold generator in out blog, Rails creates a database migration file and put it in db/migrate directory.
Let's take a look at them, they're in the directory db/migrate.
When we run the rake command, and run rake db migrate, it runs those migrations, and it creates a schema for us, and from that schema, our development database is created.
Because we can use migrations to undo the work of previous migrations, they are timestamped. We could write a migration to remove those. Therefore, the migrations have to run in the order that they were created.
Let's open the previously created blog application in our text-editor, we'll see there's the db directory. And, under that directory, there's another directory, migrate where the migration files are.
This long sequence of numbers which is a time stamp. Note that we created the post first and it's got an earlier number then this one at the very end is the only place they differ.
class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| t.string :title t.text :body t.timestamps end end end
This is just a Ruby script that is run in order to create the schema in the following section.
ActiveRecord::Schema.define(version: 20141031050956) do create_table "comments", force: true do |t| t.integer "post_id" t.text "body" t.datetime "created_at" t.datetime "updated_at" end create_table "posts", force: true do |t| t.string "title" t.text "body" t.datetime "created_at" t.datetime "updated_at" end end
The schema above is used to create development.sqlite3 database.
Rails automatically sets up applications to run in one of three prebuilt environments:
- Development - Used when we're developing the app.
- Test - Used when we run test.
- Production - Used when we deploy our app.
By default, when we run:
$ rails serverRails runs in the development environment.
So, to force rails to run in a different environment, we use:
$ rails server -e production
Let's look into more detail:
$ rails server => Booting WEBrick => Rails 4.1.7 application starting in development on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option) => Ctrl-C to shutdown server [2014-10-31 12:52:41] INFO WEBrick 1.3.1 [2014-10-31 12:52:41] INFO ruby 2.1.2 (2014-05-08) [x86_64-linux] [2014-10-31 12:52:41] INFO WEBrick::HTTPServer#start: pid=21451 port=3000
While we're running in the development environment, and if we make changes to source code, those changes are generally immediately reflected in the running application. So, if we go to the webpage and point it to the URL, we'll see the changes made in the source code will show up in the application.
To stop the server from running, type Ctrl+C.
$ rails server -e production => Booting WEBrick => Rails 4.1.7 application starting in production on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option) => Ctrl-C to shutdown server [2014-10-31 12:56:45] INFO WEBrick 1.3.1 [2014-10-31 12:56:45] INFO ruby 2.1.2 (2014-05-08) [x86_64-linux] [2014-10-31 12:56:45] INFO WEBrick::HTTPServer#start: pid=21523 port=3000
If we type, rails server -e, in order to specify the environment as production, it'll start the web server up running in the production environment instead. It'll use the production database.
And, in addition in the production mode, if we make a change to our source code, it's NOT reflected in the running application immediately.
Another thing that happens is when running in the production environment, Rails optimizes the delivery of certain assets such as CSS, Web pages HTML files. And JavaScript that needs to be delivered to the browser is optimized in this mode as well.
Now one of the architectural features that's most likely to differ between our development and our production environment is the database.
During development, we want something that's simple to use, and we're the only one accessing the database. What Rails does is it sets us up to use SQLite which is a simple file based database easy to use.
However, when we go to production mode, we're going to need something that's different than SQLite, because SQlite is not a production database.
When an application goes into production, it can receive hundreds of hits in seconds. And the database has to be able to handle those data requests.
Two of the most popular databases for production environments include PostgreSQL and MySQL.
The databases that Rails sets up for us to use are specified in the database.yml file:
# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in our Gemfile # gem 'sqlite3' # default: &default; adapter: sqlite3 pool: 5 timeout: 5000 development: <<: *default database: db/development.sqlite3 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: db/test.sqlite3 production: <<: *default database: db/production.sqlite3
Convention over configuration, we don't want to spend a lot of time configuring our databases. Rails does it for us.
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization