Tuesday, June 23, 2009

Example project for rails

Open a console in that folder and type:

rails WebAlbum --database=mysql

Now make WebAlbum the current folder in your console. All further console work is going to take place exclusively inside WebAlbum.

Although we're using the latest version of Rails, it is a fast moving target. Newer versions may break our code, so we want to keep a local copy of Rails right in our application. We do that with the freeze command:
rake rails:freeze:gems
Now our application will use the Rails code (in the vendor folder), and not the Rails code in our Ruby distribution. Next we'll check that the database settings are working. Type:
rake db:migrate

The db folder will now contain two files:
db/
development.mysql
schema.rb
So far, so good. The next step is to generate the scaffolding code for our users. We'll start off with just a couple of fields, we'll add additional fields in a moment. Type:
ruby script/generate scaffold user name:string motto:string
Rails also created a database migrate class - db/migrate/001_create_users.rb. This class inherits from ActiveRecord::Migration which provides methods to change the database structure. We need a few more fields than we defined in the scaffold script, so open this file, and modify it to look like:

class CreateUsers <>
def self.up
create_table :users do |t|
t.string :name, :limit => 40, :null => false
t.string :motto, :limit => 80
t.string :salted_password, :limit => 40, :null => false
t.string :salt, :limit => 40, :null => false
t.timestamps
end
add_index :users, [:name], :name => :users_name_index, :unique => true
end

def self.down
remove_index :users, :name => :users_name_index
drop_table :users
end
end
Right now we're at version 0, so let's update the database. Type:
rake db:migrate
If you want to check that you can revert to the previous version, then add the version number to the rake command:
rake db:migrate VERSION=0
Now let's take a look at what we've got. Start the web application, by typing:
ruby script/server
Start up your favourite browser, and type http://localhost:3000/ in the location bar. When the Rails home page appears, click on the “About your application's environment” link,

Now shut down the server (Ctrl+C), we've got some more coding to do.

Each of our users will have a password. We don't want to keep that password as plain text, because, well, someone might steal it. I'm not talking about stealing a single user's password, I'm talking about the whole database. The 'salt and shaker' process used here is probably a good enough solution to a potentially big problem. Ranting aside, let's look at the code. This is the modified app/models/user.rb file:
require 'digest/sha1'

class User <>
attr_readonly :name
attr_reader :password
attr_accessor :password_confirmation

validates_presence_of :name
validates_length_of :name, :within => 1..40
validates_uniqueness_of :name

validates_length_of :motto, :within => 0..80

validates_confirmation_of :password

def password=(pword)
@password = pword.strip
return if @password.length <> 40
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{rand.to_s}--")
self.salted_password = User.encrypted_password(self.salt, @password)
end

def validate_on_create
if @password.length <> 40
errors.add(:password, "must have between 6 and 40 characters")
end
end

def self.authenticate(name, password)
user = find(:first, :conditions => [ "name = ?", name ])
if user
if user.salted_password != encrypted_password(user.salt, password)
user = nil
end
end
user
end

private
def self.encrypted_password(salt, password)
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end
end
Now we'll need to make some modifications to the ERB template for a new user, in the file app/views/user/new.html.erb:

<%= error_messages_for :user %>

<% form_for(@user) do |f| %>
<div>
<%= f.label :name, 'Name:' %>
<%= f.text_field :name, :size =>40, :maxlength => 40 %>
div>

<div>
<%= f.label :motto, 'Motto:' %>
<%= f.text_field :motto, :size => 40, :maxlength => 80 %>
div>


<%= f.label :password, 'Password:' %>
<%= f.password_field :password, :size => 40, :maxlength => 40 %>



<%= f.label :password_confirmation, 'Confirm password:' %>
<%= f.password_field :password_confirmation, :size => 40, :maxlength => 40 %>


<div>
<%= f.submit "Create" %>
div>
<% end %>

<%= link_to 'Back', users_path %>
Now we're ready to add a user. Fire up the server again:

ruby script/server

Open the browser and go to the location http://localhost:3000/users/new. You should now see something.
And then yuo can modify this yuor own.


Next I explain how to send email using rails.
Bye everyone
:)

No comments:

Post a Comment