Rails Basics
Installation
- Install ruby and rubygems as you would any other package.
- Use gems to install rails:
sudo gem update sudo gem install rails
- To match a specific version:
gem install rails -v 2.3.5
- show installed gems:
gem list
- make links to /var/lib/gems/1.8/bin binaries in /usr/local/bin
More Installation Wisdom
I wanted to be able to develop this on my macbook too. I installed ruby and rubygems from source. I ended up getting version 1.3.1 of rubygems and 2.2.2 of rails, which was higher than on my Ubuntu Intrepid machine. So I had to update rubygems beyond the official intrepid version using this:
sudo gem install rubygems-update cd /var/lib/gems/1.8/bin sudo ./update_rubygems
Now I have to reinstall the latest gems all over again:
sudo gem install rails composite_primary_keys
There were also problems because rails has dropped default support for mysql:
sudo apt-get install ruby1.8-dev libmysqlclient15-dev sudo gem install mysql
Edits to config/environment.rb
:
- comment out this line:
config.time_zone = 'UTC'
- add this line:
require 'composite_primary_keys'
Copied old config/database.yml
to new project
Reference
- Ruby on Rails web site: http://www.rubyonrails.com/
- Documentation: http://api.rubyonrails.org/,
- Wiki: http://wiki.rubyonrails.com/
Application Setup
- Create rails app:
rails -d mysql cookbook
This creates a big directory containing all code for the project.
- Login to mysql as root and create mysql databases:
mysql> create database cookbook_dev; mysql> create database cookbook_test; mysql> create database cookbook_prod;
- Create a mysql user account and give it rights to the databases:
mysql> grant all privileges on cookbook_dev.* to 'rails_user'@'localhost' identified by 'r8!lz'; mysql> grant all privileges on cookbook_test.* to 'rails_user'@'localhost' identified by 'r8!lz'; mysql> grant all privileges on cookbook_prod.* to 'rails_user'@'localhost' identified by 'r8!lz';
- Define tables. Edit a file called create-mysql-db.sql:
drop table if exists 'chapters'; create table chapters ( id int not null auto_increment, title varchar(255) not null, sort_order int not null default 0, primary key (id) ) type=innodb; drop table if exists 'recipes'; create table recipes ( id int not null auto_increment, chapter_id int not null, title varchar(255) not null, problem text not null, solution text not null, discussion text not null, see_also text null, sort_order int not null default 0, primary key (id, chapter_id, title), foreign key (chapter_id) references chapters(id) ) type=innodb; drop table if exists 'tags'; create table tags ( id int not null auto_increment, name varchar(80) not null, primary key (id) ) type=innodb; drop table if exists 'recipes_tags'; create table recipes_tags ( recipe_id int not null, tag_id int not null, primary key (recipe_id, tag_id), foreign key (recipe_id) references recipes(id), foreign key (tag_id) references tags(id) ) type=innodb;
- Create tables:
$ mysql cookbook_dev -u rails_user -p < create-mysql-db.sql $ mysql cookbook_test -u rails_user -p < create-mysql-db.sql $ mysql cookbook_prod -u rails_user -p < create-mysql-db.sql
- Edit
config/database.yml
to have the right username/password for each database (double-check database names too).
Model
To create an object that will be linked to a database table (e.g. users):
ruby script/generate model <object/table name (singular form)>
For example:
ruby script/generate model user
This creates a file called app/models/user.rb
, which defines a User ActiveRecord class. Edit this file to add table relationships. For example, we might have cookbook/app/models/chapter.rb
:
class Chapter < ActiveRecord::Base
has_many :recipes
end
Other relationship functions include belongs_to
and has_and_belongs_to_many
.
Find example:
found_user = User.find(userid)
found_user = User.find(:first, :conditions => ["email = ?", email])
Controller
To control an object's behavior:
ruby script/generate controller <object (single form)> <list of actions>
For example:
ruby script/generate controller user add delete login logout
This command creates a file app/controllers/user_controller.rb
, which defines a class UserController
. The class defines four stub methods: add
, delete
, login
, and logout
.
Logging from a controller
class HomeController < ActionController::Base
def index
logger.info 'informational message'
end
end
This will show up in the server log. Log levels are debug, info, warn, error, and fatal. In production, debug entries are omitted.
View
The view files are created automatically for each action specified at controller creation. The same command that created the UserController
class above also created four files in app/views/user/
: add.rhtml
, delete.rhtml
, login.rhtml
, and logout.rhtml
. A user accesses the view by opening http://www.example.com/my_app/add
.
Info on select
vs select_tag
vs collection_select
: http://shiningthrough.co.uk/blog/show/6
Editing .rhtml files
- Use
<% ... %>
to hold ruby code that should be processed. - Use
<%= ... %>
to also print the output of the code. - Comments:
<%
=begin
This style will work with scriplets too <%= now.broken.function(foo) %>
=end
%>
<% if false %>
so will this style <%= now.broken.function(foo) %>
<% end %>
Access to data
- The view can access the controller's instance variables like
@name
. - The view can't access any of the controller's methods, class variables (
@@my_class_name
), or constants. - The view can access global constants defined in
config/environment.rb
.
Layouts/Templates
- To apply a layout to every page in your web application, create a file called
app/views/layouts/application.rhtml
. It should look something like this:
<html><head><title>My Website</title></head>
<body>
<%= @content_for_layout %>
</body></html>
- Make a view-specific template by creating
app/views/layouts/my_view.rhtml
. - Layouts can access all of the same data that views can.