Understanding Ruby on Rails

June 8, 2006 § Leave a comment

This presentation (pdf) explains the underlying
philosophy and technologies that make Ruby on Rails so compelling (at least
IMHO). It includes a tutorial for Rails 1.1.2 that covers:
? creating SQLite databases using migrations
? generating models and
scaffolds
? writing controllers by hand (w/o
generators)
? rjs and rhtml templates for dynamic HTML (aka
AJAX )
? creating fixtures for unit and functional
tests

While far from complete, I tried
to create a very brief example that illustrates all the key Rails concepts that
had previously intimidated me, as well as delineate the “religious” issues that
make people love/hate Rails.

While
written for Mac OS X, other than using TextMate (“mate”) for editing this should
work fine on any UNIX platform (and even on Windows, if you can figure out the
equivalent shell commands).

You can
download the resulting sample code, or [Read More] for the demo script
(which duplicates the content in the presentation).

DEMO
SCRIPT

rails
spot
# create directory
tree

cd
!$

mate config/database.yml
.
# open in text
editor

development:

adapter: sqlite3

dbfile:
db/spot_development.db

test:

adapter: sqlite3

dbfile:
db/spot_test.db

script/generate
model Thing
# model class and
helpers

mate
db/migrate/001_create_things.rb


t.column :name, :string # add

t.column
:state, :string # add

rake
migrate

sqlite3
db/spot_development.db ‘.dump things’

script/generate scaffold
Thing

script/server
-d
#
detached;

open
http://localhost:3000/things

mate
config/routes.rb

map.connect ”,
:controller => “things”

mv
public/index.html{,.old}

open
http://localhost:3000/

script/console

thing=Thing.new({:name => “#1”,:state =>
“Cursed”})


thing.name


thing.save


Thing.find_all


quit

script/generate model
Hat
# another model
class

mate
db/migrate/002_create_hats.rb


t.column :color, :string # add

t.column
:thing_id, :integer # add

rake
migrate

mate
app/models/hat.rb

belongs_to
:thing # has a foreign key


validates_associated :thing # requires an
owner

validates_presence_of :color #
requires a color

mate
app/models/thing.rb

has_one :hat
# converse of belongs_to

def before_destroy
# cleanup foreign key

@hat =
Hat.find_by_thing_id(id)


@hat.update_attribute(‘thing_id’,NIL) #unless
@hat.nil?


end

script/console

thing0 = Thing.find_all[0]

hat0 =
Hat.new({:color=>”Blue”,
:thing_id=>thing0.id})


hat0.save


hat0.thing.name


thing0.hat.color


quit


#
Template

mate
app/views/things/edit.rhtml

<p
id =”hat”>

<% if @thing.hat.nil?
%>

<%= render :partial => ‘add_hat’
%>

<% else
%>

<%= render :partial =>
‘show_hat’ %>

<% end
%>

</p>

mate
app/views/layouts/things.rhtml

<%=
javascript_include_tag :defaults
%>

touch
app/views/things/_{add,show,new}_hat.rhtml
;
mate

<%= link_to_remote ‘New Hat’,
:url => {:action => ‘begin_hat’, :id => @thing}
%>

<%=h @thing.hat.color %>
hat

<%= link_to_remote ‘Delete’, :url
=> {:action => ‘destroy_hat’, :id => @thing}
%>

<%= form_remote_tag :url =>
{:action => ‘create_hat’}
%>

<!–[form:hat]–>
<p><label
for=”hat_color”>Color</label><br/>


<%= text_field ‘hat’, ‘color’
%></p>

<%= hidden_field ‘hat’,
‘thing_id’
%>

<!–[eoform:hat]–>
<%=
submit_tag ‘Create Hat’ %>

<%=
end_form_tag %>

mate
app/controllers/things_controller.rb

def
begin_hat

@hat =
Hat.new

@hat.thing_id =
params[:id]

end

def
create_hat

@hat =
Hat.new(params[:hat])

if
@hat.save

flash[:notice] = ‘Hat was
successfully created.’


else

flash[:notice] = ‘Hat created
failed!’

render :action =>
‘begin_hat’


end

@thing = @hat.thing # needed for
template

end

def
destroy_hat

@thing =
Thing.find(params[:id])


Hat.find_by_thing_id(params[:id]).destroy

end

touch
app/views/things/{begin,create,destroy}_hat.rjs
;
mate

page.replace_html ‘hat’, :partial
=> ‘new_hat’

page.replace_html
‘hat’, :partial =>
‘show_hat’

page.visual_effect :shake, ‘hat’,
:duration => 1

page.replace_html
‘hat’, :partial =>
‘add_hat’

page.visual_effect :highlight,
‘hat’, :duration =>
1

open
http://localhost:3000/things/edit/1

rake
test
# Run pre-generated unit and functional
tests

mate
tests/fixtures/hats.yml
# Ensure color is
present

first:

id: 1

thing_id:
1

another:

id: 2

thing_id:
2

mate
test/functional/things_controller_test.rb

fixtures
:things, :hats

rake
test_functional
# Should now all
pass

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

What’s this?

You are currently reading Understanding Ruby on Rails at iHack, therefore iBlog.

meta

%d bloggers like this: