Ruby for Programmers – Part 17: On The ActiveRecord

This goes a little into how to run SQL. You don’t need to know everything, but this is a great tutorial on straight SQL. Good news though, you don’t have to touch any SQL for this. Here’s the tl;dr:

  • A SQL table is a lot like a spreadsheet. You have rows and columns. You should have a table for each data model.
  • Tables and their columns need to manually created and removed. When you need to make a new column, you need to manually tell the system that it needs to be created.
  • “Primary” column(s) are unique and define it. Generally speaking this is just an id number. Rails sets it up so that the database will auto increment the id so you don’t have to worry.

So let’s setup our database. We’ll be using Postgres, so we need to install it. For Macs, use Postgres.app. It’s simple and easy. Postgres provides an installer for Windows. And Linux can use your favorite package manager.

And once it’s setup, we need a database (set of tables) to put it into. You can use the included GUI or the command “createdb” to create a database.

Then we need to install the pg gem, which might be a small issue on any machine. For example on Mac you may need to run env ARCHFLAGS="-arch x86_64" gem install pg -- --with-pg-config=/Applications/Postgres.app/Contents/MacOS/bin/pg_config to give it the right config file to build the C extension against. Googling eventually finds the right answer.

Hopefully now you have the gem installed, and we can run bundler with pg and ActiveRecord:

And the Railtie:

Now we need to setup the postgres password. Create a new file, config/database.yml, to put the postgres password that you used to setup the postgres root password:

Don’t forget to change the pertinent parts.

With this we can create our first migration to get the database to have the right table information. So let’s create that file:

So that’s a mouthful that’s easier explained in the Rails guide. In short this creates a table with the listed columns. By default the id primary column is create for you, as well as an automatic “created_at” and “updated_at” columns too.

To run our migration you need to run bundle exec rake db:migrate. This occurs whenever you need to run any database migrations.

And now let’s update our Page model:

Yep, it is that small. Rails is smart enough to know that the attributes is the name of the columns. It also includes a finder method and handles saving to the database for you. Of course we need to create the “create page” page since we have an empty database:

Notice how we don’t even need to create a new form? It can re-use the same form because it knows that the data is a new entry instead of an old entry and redirects accordingly.

Lastly, there’s associations, which you can read on the Rails guide. We’ll be going into associations when we start the main project, but for now the guide will do.

And that gets you up to speed with all the major parts of Rails. There’s still tons more to learn, but there’s better guides for what you need after this point:

And that’s it. This last part is available on Github.

Ruby for Programmers – Part 16: Data Models

By now we can render stuff to a webpage, which is cool, but there’s no way to make or save any data, so let’s fix that. Since we’re making a CMS thing, we’re going to need the ability to make and save data. So let’s start by making a silly flat-file data-model system in a new folder “db”:

To work with this data, we’re going to create a special class called “Page” to handle our pages. Generally speaking, any class that exclusively deals with data is called a “model”. Thus, our new file is going to be put in app/models/page.rb:

This is a bunch of code to drop, but all it really does is load a JSON file and allows you to search for data.

And let’s modify our controller and view to use the new page data:

If you just browse to “/page/page-2”, it will show the data for that page. Now that’s nice, but we can make it better.

Let’s start adding some Rails methods to the Page class to start adding some magic. We’re going to start with ActiveModel, which contains a bit of magic without requiring much more. So first let’s add it to our Gemfile:

And add it to our list of railties to preload it:

And so now we can add some specialized functions. First is ActiveModel::Model which adds some internal specialized functions:

  • ActiveModel::Naming – which creates string names from your class names. Very useful for generating routes (and table names later on).
  • ActiveModel::Translation – which automatically creates human names from the attribute name, and allows you to translate them to other languages if the translation file is available.
  • ActiveModel::Conversion – which adds a few helper functions for routing
  • ActiveModel::Validations – which we’ll get into a little bit later
  • And a few internal methods like automatically creating the initialize function for us.
  • So let’s add it:

    That’s already better, but we have no way of saving. So let’s add that:

    Admittingly, not the most optimized flat-file format but we’ll figure that out later. Now that we can edit data and have added the ActiveModel::Conversion (via Model), we can now use resources on the routes. This is just an automatic route creator that does a bunch of magic for us.

    Try a bundle exec rake routes to see what our routes looks like:

    So this creates a bunch of really common routes for us. Let’s use them. First we need a new class method called “find” that lets us find by a direct id number:

    And create a new controller:

    And our edit page:

    This takes advantage of an ActionView form builder which automatically creates the form based on attributes and fills in the default value if it exists, and routes to the correct page if the resource routing exists.

    Of course we need to create the update and show functions too:

    Here we simply see the page attributes getting updated. Now that we have the ability to edit pages, lets throw some magic in the monkey works. First, callbacks:

    You should be familiar with callbacks, and this is the same. You can define (or have defined for you), various callbacks. For instance, this touches a new “updated_at” attribute which might be useful.

    Another useful module is ActiveModel::Validation which allows one to check to see if the data validations certain conditions. For example, you may want a name or title or not be blank and have a certain minimum. For example you could do this:

    But there are built-in validators for common validations:

    The rest of the validators are on the Rails guide.

    That’s the basics of attributes and how it can modify your saving. Now let’s focus on databases.

    As always, code examples are on Github.