Wednesday, 9 July 2008

The Model Part 1 - Creation

The Ruby on Rails design pattern is the model-view-controller.

The model is the connection to the database, but it is also the class (in an OO sense) representing your data. Any methods that would go inside the class, should go into the model.

Creating a Model
Rails can create a model in any of four ways. If you also want a controller and default views (for basic CRUD operations; new, show, edit and delete), generate a scaffold. If you want a blank controller with your model so you can create your own views, generate a resource. Otherwise you can generate a model, say if you just want a table to populate a drop-down list. Finally, you can just create a new file, and code it directly, of course.

The model name should be something appropriate, in the singular, either in CamelCase or under_scored lowercase. The generated files and classes will be named (Ruby on Rails has a built-in function for deriving plurals):
you named it: BlogPost or blog_post
database table: blog_posts
model class name: BlogPost
model class file: blog_post.rb
model class test file: blog_post_test.rb
controller class name: BlogPostController
controller class file: blog_posts_controller.rb
controller functional test file: blog_posts_controller_test.rb
views folder: blog_posts

The options are a space separated list of attributes, like this:
name:string body:text post:references

Note that an ID column and time stamp columns are automatically added (the latter note creation and last modified date and time).

The "references" type in the example allows you to relate your table to another table. If you have several comments in a blog for one post, then each comment references the post. Rails will generate a post_id column. This means you should create the parent model, before the child (posts before comment). To get this to work properly, you need to associate the child model with the parent with a belongs_to - more on that in a later post.

The types allowed are:
:primary_key, :string, :text, :integer, :float, :decimal,
:datetime, :timestamp, :time, :date, :binary, :boolean

Some examples
ruby script/generate scaffold BlogPost name:string body:text
ruby script/generate resource BlogComment body:text post:references
ruby script/generate model User
Column names to avoid: Rails will generate a method with the name of your columns, so you are firstly restricted to lowercase letters, digits (but not at the start) and underscore. Furthermore, you should avoid any existing method names, as there will be a conflict. Others to avoid are: type (used by Rails in Single Table Inheriance to hold the classname), graph (seems to throw PostgreSQL; but not MySql). I would also avoid these: timestamp, data, time, number, text, date.

More here:

Once the model is generated, migrate to the current database version.

Modifying a Model's Columns
You can do this through a generated database migration, or revert your database back, edit your existing migration, and then migrate back to the current version. The latter keeps the number of migrations to a minimum, but could lead to other problems, especially if others working on the project are not using the new version. *

If you choose to use a database migration to add a new column, you need to give the migration a name that includes the table name, such as AddCategoryToPosts.
ruby script/generate migration AddCategoryToPosts

The migration file produced is quite different to the file used to create a new table, as it uses the add_column method, as opposed to the create_table method. This seems to preclude the references type (though I could be wrong about that), so you would have to do:


Try to get it right from the start!

Reference for migrations:

Part 2 will look at the code inside the model.rb file.

Struggling with Ruby: Contents Page

No comments: