Saturday, February 7, 2015

Modelling Categories

Earlier I talked about how I'm going to start with three models: Users, Categories, and Pages. I got the basics of Users done in the last post, so let's do Categories and Pages now. Each Page is going to have one and only one Category, while a Category will obviously have many Pages. Here is my starting point for these models:

A Category is going to have these attributes:

  • a name,
  • the order of its appearance on the list (using an integer for now),
  • a flag to determine if it's should be private to the user,
  • a short description of the category.
So, we have
  t.string  :title
  t.integer :order
  t.boolean :private
  t.text    :description
Create the Category model using the following scaffold:
$ rails generate scaffold Categories title:string order:integer:index private:boolean description:text

A Page has the following attributes:

  • a name, order, and a boolean flag for private entries
  • the category it belongs to
  • the contents
How are we going to model the contents though? Is everything going to be text? Can we put pictures? PDFs?

I'm going to start by just putting text inside the contents. However, if we have something like t.text :contents, i.e. putting the whole article into one text entry in the database, then every time we need to edit the entry we need to trawl through the whole article. It might make more sense to split the contents into smaller chunks.

I'm therefore going to create a new model called Section as follows:

  t.belongs_to :page, index: true
  t.string  :title
  t.integer :order
  t.text    :content

  t.integer :page_id
I'm not sure if I need a boolean flag for private sections, but this can always be added later. The belongs_to variable tells rails that each Page has many Sections. The :page_id variable gets used by the foreigner gem to set a database level foreign key (something I prefer).

Similarly, the migration for Page is

  t.belongs_to :category, index: true
  t.string   :title
  t.integer  :order
  t.boolean  :private
  
  t.integer :category_id

What's left is to link Sections to Pages and Pages to Categories. In app/models/section.rb
  class Section < ActiveRecord::Base
    belongs_to :page
  end
and in page.rb and category.rb
  class Page < ActiveRecord::Base
    belongs_to :category
    has_many :sections
  end

  class Category < ActiveRecord::Base
    has_many :pages
  end