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.