Sunday, January 27, 2008

Rails 2.0 Step by Step (part 2)

This is the second part of my series.
Part 1 is here.
Thanks for all of the great comments and help.

I think one of the most important comments came from enklare who pointed out that with Rails 2.0 you should explicitly set the database when you create a new Rails app by using the -d flag.

Instead of using the command

work$ rails exchange
use the command

work$ rails -d mysql exchange

To create the exchange app.

( typing 'rails --help' at the command line will give a short list of available options)

This will help Rails configure your application if you have other databases like SQLLite installed.

SQLLite is the default database for Rails as of Rails version 2.0.

-------------------------------------------------------------------------------------------------------------
Rails 2.0 Step by Step
(part 2)


Model View Controller

The Model View Controller(MVC) design pattern was first described in 1979 by Trygve Reenskaug while working at Xerox on Smalltalk. MVC is not a new syntax construct like an if statement or a data type like an array or int but more a way of looking at how to structure programs and divide the parts up in a logical and useful way.

Following MVC guidelines has been shown to organize applications in a way that makes them easy to manage and maintain. After working with the MVC pattern for a while you will grow to see the benefits that the division of labor produce.
Rails is a strict MVC frame work.

If you stick to the MVC pattern you will find Rails easier to understand and use.


Model

The Model is all about the data. This includes getting the data in and out of the data store. The scaffolding we set up in part one gives us the four basic operation of using a data store Create,
Read, Update and Destroy. Other data centric functionality also goes in the Model. Searching for data, manipulating data, validating input, and possibly editing the data for display (although sometimes this might logically be part of the view as well).

View

The View renders the Model in an interactive displayable format. It takes the data in the Model and paints it up on the screen for you to see and interact with.


Controller

The Controller responds to events communicating with the Model and the View. This is like the Main loop in a state machine waiting for events like user actions or Model data to show up and reacting as the program dictates to those events. Let's look at the Model View and Controller created by the Rails scaffolding, and start updating each of them with our own code.

We'll make changes to the Model and to the view and then get into the controller and migrations in the next installment.


The Model in Rails
The scaffold command created a model in the app/model/ folder called movies.rb.

Look in ~/work/exchange/app/models/movies.rb and you'll see a pretty sparse Model



The file is a Ruby file and the lines
class Movie <>
end

declare a class named Movie that inherits from class ActiveRecord::Base. Active Record is one of the gems installed along with Rails.


Looking in the Ruby on Rails api documentation for ActiveRecord::Base in the Classes section shows all of the methods, attributes, exceptions and other parts available in class ActiveRecord::Base. We'll see that an instance of the class Movie could be called anything but the Rails convention is to use a variable named movie or @movie. You will see this in code covered below.


The :: symbol is the Ruby scope operator. In ActiveRecord::Base it means that you are referring to the Base of ActiveRecord and not some other base.


We can customize our Model by adding code here just as in earlier versions of Rails. By adding our own code Movie will inherit from and extend the ActiveRecord::Base class.

The line

validates_presence_of :title, :description, :one_sheet_url

will check to make sure that there is, at least, some value entered in the fields on the form.



Let's create a new movie and see how the model behaves when we leave out the description and one sheet image location.


The Model won't allow a new row to be created if these fields are blank. Rails provides many validation features out of the box. The errors are listed at the top of the screen along with a description of the problem encountered and the fields with errors are highlighted in the form.

Taking a cue out of the AWDWR depot app we can check the format of data entered too.



Let's add some data but give the wrong file extension to our image to see how the model handles the input:


The model correctly flags the badly formatted entry as an error and prints a message. Note that the message displayed is the customized message we put in our model's validation "must be a URL for a GIF, JPG, or PNG image".

Fixing the file extension allows the model to accept the presence and format of our input. By fixing this error the Model saves the movie instance as a row in our table.


There are plenty of places to go to learn more about validation in Ruby on Rails. The Rails documentation is also a good resource as well as the models available to do validation.

Placing logic like this in the model, instead of embedding it in the logic for the screen, helps reduce duplication and ensures that all data being entered undergoes the same validation regardless of the interface used to enter the data.

The View in Rails

The view created by our scaffolding is pretty plain. Looking in the /app/views/ directory you will see two directories, layouts and movies. from the exchange directory change into the views directory and you can see them.
exchange$ cd app/views/
exchange/app/views$ ls -p
layouts/ movies/


movies/ has files that correspond to the various pages we have used in this demo so far
exchange/app/views$ cd movies/
exchange/app/views/movies$ ls -p
edit.html.erb index.html.erb new.html.erb show.html.erb

The .html.erb extension tells us that these files are chunks of html with embedded ruby. Looking at the file show.html.erb shows the html and the embedded ruby code.

Comparing this to the successfully created entry above shows where the Title:, Description:, and One sheet url: come from in our html. The parts between the '<%=' and the '%>' are the embedded ruby code. The code here displays the title, description, and one_sheet_url of the movie instance in @movie.

The two pieces of embedded Ruby with 'link_to' at the bottom show the buttons for Edit and Back. This code is where the text 'Edit' and 'Back' come from as well a the path or action for the controller to take when the button is pressed.

For the 'Edit' action the instance @movie is also passed as a parameter.

The 'h' in the '< % = h...% >' is there to strip any unwanted html and is a little beyond the discussion at this point.

Comparing this to the screen you cannot see where is no place for the green text "Movie was successfully created" originates.

The show.html.erb file is also missing the html, head, and body tags needed for a web page.
We'll find these in the layouts directory.
exchange/app/views/movies$ cd ..
exchange/app/views$ cd layouts/
exchange/app/views/layouts$ ls -p
movies.html.erb



The scaffolding has created a default layout for the movie view called movies.html.erb. This file contains the parts needed to build a valid web page including our DOCTYPE, title, html, head and body tags, as well as where the color green came from for the friendly notice "Movie was successfully created".

The <%= yield %> is where the chunks of html from the files under the /views directory go when a page is built for display. The controller matches the chunk of html from the views/ directory to the action. Listing all of the movies uses the index.html.erb file, creating a new movie uses the new.html.erb file, editing an existing movie uses the edit.html.erb file, and showing one existing movie uses the show.html.erb file.

Also note that our original web page uses a css stylesheet called 'scaffold'.


Customized View
Side Note:
I spend most of my professional time optimizing queries. Sounds exciting, I know. I don't have the gene for good design, so I'll keep it simple. There are plenty of people in the Rails community with great design ideas so there are plenty of better places for you to go to get layout tips.

Add some div id tags to our page and create a simple stylesheet. First change the movies.html.erb



The scaffold command created a stylesheet in the directory /exchange/public/stylesheets called scaffold.css. Create one called exchange.css that looks like

/* Global styles */
/* START:notice */
#notice {
border: 2px solid red;
padding: 1em;
margin-bottom: 2em;

background-color: #f0f0f0;
font: bold smaller sans-serif;
}
/* END:notice */
/* Styles for main page */
#banner {
background: #0099cc;
padding-top: 10px;
padding-bottom: 20px;
border-bottom: 4px solid;
/* font: small-caps 50px/50px "Times New Roman", serif; */

font: small-caps 50px/50px serif;
color: #000080;
text-align: center;
}
#banner img {
float: left;
}
#columns {
background: #9999ff;

}
#main {
margin-left: 12em;
padding-top: 4ex;
padding-left: 2em;
background: white;
}
#side {
float: left;

padding-top: 1em;
padding-left: 1em;
padding-bottom: 1em;
width: 10em;
background: #9999ff;
}
#side a {
color: #00ffff;
font-size: small;

}
h1 {
font: 150% sans-serif;
color: #226;
border-bottom: 3px dotted #77d;
}


Starting script/server and pointing your browser to http://localhost:3000/movies should give you something like this

It looks a little nicer, but the listing can be made nicer and we can save some duplication in the edit and new pages with a partial form. (The rails.png logo was put in the /exchange/public/images directory by the rails command when our app was created).

Partials

If you compare the new.html.erb and the edit.html.erb files you will see that they are almost exactly the same.

Look at the do loop between the <% form_for(@movie) do |f| %> and <% end %> and the only difference is the text passed in the line with 'f.submit'. The new page has the text "Create" and the edit page has the text "Update".

Make a copy of this section from either file and paste it in a file called _form.html.erb in the same views directory.


Edit the text passed in the 'f.submit' line and use a variable named label_text instead so the /exchange/app/views/movies/_form.html.erb file looks like this


The variable label_text will be passed in from the edit or new pages with the correct value inside. Make the edit.html.erb page look like this


Everything between the form_for do and the end is replaced with the one line
<%= render :partial => "form", :locals => { :f => f, :label_text => "Update"} %>

Similarly , edit the new.html.erb file so it looks like


This will render the partial _form and pass it the local variables and the variable label_text with either the value "Create" or "Update". Let's see if it works by editing one of our existing movies.


Things look the same as before, which is exactly what we wanted.

Creating a new movie also continues to work as before


Making a list, checking it twice
let's make the listing look a little more organized. Edit the index.html.erb file so it looks like this:



<div id="movie-list">
<h1>Movie Listing</h1>

<table cellpadding="5" cellspacing="0">
<% for movie in @movies %>
<tr valign="top" class="<%= cycle('list-line-odd', 'list-line-even') %>">

<td>
<img class="list-one-sheet" src="<%= movie.one_sheet_url %>"/>
</td>

<td width="60%">
<span class="list-title"><%= h(movie.title) %></span><br />
<%= h(truncate(movie.description, 80)) %>
</td>

<td class="list-actions">
<%= link_to 'Show', movie %>
<%= link_to 'Edit', edit_movie_path(movie) %>
<%= link_to 'Destroy', movie, :confirm => 'Are you sure?', :method => :delete %>
</td>
</tr>
<% end %>
</table>
</div>
<br />
<%= link_to 'New movie', :action => 'new' %>





Then add a section to the exchange.css file for our movie-list div id tag that looks like

#movie-list .list-title {
color: #244;
font-weight: bold;
font-size: larger;
}

#movie-list .list-one-sheet {
width: 60px;
height: 70px;
}


#movie-list .list-actions {
font-size: x-small;
text-align: right;
padding-left: 1em;
}

#movie-list .list-line-even {
background: #ffccff;
}

#movie-list .list-line-odd {
background: #d0d0d0;
}



The index.html.erb file should now render a page that looks like


here are a few one sheet images for you to play with (you might have to rename them).





Copies of these images should be placed in the /exchange/public/images/ directory.

What has been done so far?
  • Reviewed the Model View Controller design pattern
  • Added validation rules to our model
  • Added a banner and sidebar to our pages
  • Created a style sheet for our app
  • Used a partial form to get rid of code duplication
  • made a prettier listing for our main index page
  • added some graphics to the /public/images directory


Next time I'll look at the controller and a Rails 2.0 trick for adding new columns in a migration.

192 comments:

Anonymous said...

Thanks ...

You are doing awesome work..!!

Shadownerd said...

Wonderful tutorials!
I'm updating my RoR understanding to 2.0.
Thank you!

Michael Carlyon

chi wai lau said...

Thank you!

Anonymous said...

Thank you for taking the time to present an easy to follow update to 2.0.

Anonymous said...

This might be a dumb question, but where does the h come from in the for loop in index.html? Is this a convention in Ruby (or in Rails) to refer to an element in a data structure in a loop as h? If not, where is h chosen?

Thanks for a wonderful tutorial!

Sean Lynch said...

Anonymous 11:34,

Are you asking about the h() function used in the line:
h(truncate(movie.description, 80)) ?

This is a method from erb that escapes html. Any html run through this function won't be interpreted.

You can learn more by google-ing ERB::Util .

The modules for erb are available to you in Rails.

Anonymous said...

RE: h() function

Thank you very much for clearing that up!

hamrin said...

Thanks for continuing the tutorial.
After I made the first set of changes to the CSS files (before getting into Partials) the movies are not listed. I do get the new banner with the png and the title, the sidebar is blue with the word Sidebar, but there are no movies listed. Lookig in the source in the browser there nothing "yielded" between the div id="main" and the /div
I made the changes to movies.html.erb and created the exchange.css file.
Do I have to change anything in index.html.erb? It doesn't seem to get invoked, the h1 string "Listing movies" is never presented by the browser.

I am running Safari on Leopard on a MacBook.
Rails 2.0.2, Ruby 1.8.6

Thanks Sean

Sean Lynch said...

hamrin,

I've turned on my e-mail address in my blogger profile. can you e-mail me your movies.html.erb and index.html.erb files?

I'll look them over.

clicking on my name in the comment should get you my profile.

Thanks

Anonymous said...

excellent!!!. I just got my first app running. I would like to know how to use existing database table to create a similar web application.

appreciate ur reply

Anonymous said...

I am not sure if my previous comment went thru.. I am posting again.

how to create rails project with existing table in the database?

Dennis Yarborough said...

Thanks for taking the time to document this Rails 2 Tutorial! I just wrapped up part 2 and everything works great, with the exception I can't get the images to display. I'm sure that it's something I screwed up while typing.

Again, thanks for the tutorial! It's the best tutorial I've found yet for 2.0.

Sean Lynch said...

Dennis,

Check the extensions on the ends of the image files.

They might be *.jpg or *.jpeg. I was working fron Linux at home and Windows at work, and I noticed the difference in my two apps.

Make sure the names in the one_sheet_url match what was entered in the app. You can use the edit function in the app to make the change.

Sean

bcurtu said...

Really good tutorial, thanx

Max Stepanov said...

"with Rails 2.0 you should explicitly set the database when you create a new Rails app by using the -d flag."

This is misleading. What you probably meant is that the default database in rails is SQLite now, and you need to specify explicitly if you want to use anything else, including mysql.

Sean Lynch said...

You are correct Max, SQLite 3 is now the default database for Rails.

I didn't have SQLite installed on my debian box so Rails went with MySQL.

Anonymous said...

Thanks for the tutorial! All of the tutorials I've found thus far are for previous versions of rails and magically explode upon viewing (not good for a rails noob!)

I ran through your walkthru and found one error in the following passage:

Edit the text passed in the 'f.submit' line and use a variable named label_text instead so the /exchange/app/views/_form.html.erb file looks like this


I received an error stating it could not find the partial form file. Upon further investigation I discovered on my system the path should be:
/exchange/app/views/movies/_form.html.erb

Cheers :)

hammer said...

Very nice tutorial - it really helped me gain insight on where the other tutorials were failing because of 2.0.


One comment on usability - I would suggest you somehow differentiate on your system listings between what a person is supposed to type, and what the listing produces.

For example you have:

exchange/app/views$ cd movies/
exchange/app/views/movies$ ls -p
edit.html.erb index.html.erb new.html.erb show.html.erb


where something like:

exchange/app/views$ cd movies/
exchange/app/views/movies$ ls -p
edit.html.erb index.html.erb new.html.erb show.html.erb

might be a little easier. This was a particular issue for me in the first tutorial -- for example, where you generated the model and the command went to two lines.

I can't wait for part 3!

Sean Lynch said...

Thanks for the corrections and suggestions!

Sean

David said...

Thanks you, this is just what I needed!

Jack said...

Thank, the tutorial is damp good. Is there part 3 there?

Jack said...

Thanks you. Where is part 3?

Sean Lynch said...

Part three is not done yet.

Sean

Anonymous said...

great tutorial..

but there isn't the code of the 'list-title' class of "exchange.css"

Michael said...

I really like your tutorial so far... i have got to the part where you start editing the CSS. I have a problem though. For some reason my movies view is not being processed... it just goes straight to the action views (i.e. new, show, etc...). When i look at the source from with in Firefox and IE, neither show any of the header info or the body tag, all i see is the code from the action views. Any ideas?

Michael said...

Never mind, I figured out my problem... the path to my exchange folder was c:\[RubyProjects]\exchange. I use the brackets to bypass sorting order and force the folder to the top of the list... turns out rails doesn't like this. I removed the brackets and it fixed my problem.

ahmed said...

Thank for such a good info source.

Anonymous said...

I really appreciate you taking the time to create an easy to follow tutorial.

For a Novice like myself, it gives me a good idea of how to get started. I look forward to new tutorials from you!

Thanks

redge said...

I appreciate you taking the time to write these tutorials. As someone new to Rails, tutorial-wise this is a bad time to be starting.

Bill said...

Awsome...

You are 2 for 2. I've struggled through and not finished at least 8 tutorials between NetBeans and Ruby on InstantRails. I even got the app to work on Vista!

soumas said...

It's a real bad time to start programming with RoR because there are no 2.0-beginner-tutorials.
Thank you very much for your work - it kept from giving up RoR ;-)
I'm looking forward to read next units of your tutorial.

thx tomy

Anonymous said...

Using Rails 2.0 RESTful support show how to create a new row in a table by editing some of the attributes of an exiting row. Thus the user would not have to re-type the things that do not change.

Anonymous said...

Last night, I spent HOURS wondering why I absolutely could not get scaffolding to work like all the tutorials...

Luckily I found yours this morning!

THANK YOU for such a clear and informative tutorial!

Mike said...

Bravo! Keep up the good work.

To release a new version of *anything * that breaks existing paradigms without a new tutorial/quick-start is just bad form. Cheers to you for filling that gap.

Anonymous said...

Yes I agree !
It is a very clear tutorial, very useful moreover, when there is almost no toturial about Rails 2.0 (at least none I could make work...).

Anonymous said...

Thanks. Good work. Please continue with more features of Rails 2.0. Interesting article.

Leif said...

I cannot destroy? I get an error "Unknown action"
"No action responded to " and then the numerical id of the movie.

What's going on here? My edit, show, and new all work just fine.

Marianna said...

Wow! A very clear, easy to follow tutorial.I am a complete newbie to Rails and this helped me a lot to get movin. Thnx.

Wintermute said...

I was having troubles with this, until I created a new project and named it project1, it seems like all my previous names were in the plural form, causing some sort of bug!

Anonymous said...

I am a RoR beginner. Very useful tutorial!

Well done. I am waiting for your next run.

Doktor said...

If I add validate_presense_of I get a class error. It's not finding any of the class methods. Probably my classpath. Any ideas?

Anonymous said...

One more vote of thanks.

After spending ages trying to convert existing tutorials and a book to Rails 2.0, you really got me up and running!

Thank you so much!

Looking foward to part 3

ikennb said...

This "movie" tutorial allowed me to stay on track. Thanks.

chrisboote said...

Leif said...

I cannot destroy? I get an error "Unknown action"
"No action responded to " and then the numerical id of the movie.

What's going on here? My edit, show, and new all work just fine.


I had the same problem, and fixed it by renaming the destroy action in the controller to kill
It appears that @movies.destroy was causing some sort of recursion within the destroy action

Hugo said...

I am also having a problem deleteing records.

I am using...

link_to 'Destroy', movie, :confirm => 'Are you sure?', :method => :delete

...and it is showing the record instead of deleting it

I also tried what is shown in the tutorial, does not work.

ikennb said...

I an also having an issue with destroy? Please explain...the fix

Sean Lynch said...

Thank you all for finding the bug in destroy code.

It worked for me because the file I am using is not the one I showed in the posted article.

I apologize for this mistake!

The file exchange/app/vies/movies/index.html.erb that I posted has an error.

look for the section that has a class labeled list-action and use this code:

<td class="list-actions">
<%= link_to 'Show', movie %>
<%= link_to 'Edit', edit_movie_path(movie) %>
<%= link_to 'Destroy', movie, :confirm => 'Are you sure?', :method => :delete %>
</td>

This should allow you to destroy a movie entry.

balgarath said...

Great tutorial. I was able to find more tutorials at RailsonEdge and RubyPlus.

Calvin Dodge said...

Thanks - it's great to _finally_ find a good tutorial for Rails 2.0 (all the other ones I'd tried were for earlier versions, and a basic application wouldn't "just work" after the initial commands to create scaffolding and tables.

Anonymous said...

Thank you so much. I'm new to Rails and your information was a great help.

Anonymous said...

Thanks a bunch for your tutorials. I'm new to Rails and that helps a lot! I have a question though: now that I've ran scaffold and it generated all that initial code/html, I want to add a new column to my table. How do I get scaffold to re-generate all the files to take into account that new column? I could probably destroy the all thing and somewhat start from scratch but I'm hoping there is a better way. Any suggestion?
Thanks

Sean Lynch said...

Rails 2.0 does not support scaffolding out of the box, but it can be added as a plugin.

See this article for more info.

Anonymous said...

Just another rails newb posting many, many thanks! Can't wait for the next part in the series.

GoldPlusCash said...

Great tutorial. It worked perfectly. Thanks a bunch!

Anonymous said...

Perfect job...

cerdal said...

Many thanks from yet another newbie, who has tried adapting other tutorials without success, and was getting rather disheartened until he stumbled on this!

Anonymous said...

You're doing a perfect job, congragulations...
Engin

Anonymous said...

Getting this error in part 2 of the tutorial

A regular expression must be supplied as the :with option of the configuration hash

Here is what I have in the Movie class. It looks like it matches the tutorial

validates_format_of :one_sheet_url,
:width => %r{\.(gif|jpg|jpeg|png)$}i,
:message => "must be a url for a gif, jpeg or png images"


And help would be helpful.

Curt

mister snickers said...

Thank you so much for this tutorial. My 100 bucks worth of books had been rendered pretty much useless as I haven't been able to get anything started.

Now I can and the kids can give their two weeks' notice at the mill.

Sean Lynch said...

Anonymous 7:09,

Change the reference

:width =>

to

:with =>

-Sean

Sean Lynch said...

Mister Snickers (and a few others),

I believe that you can get old style scaffolding back by adding the scaffold plugin...

See This article for how to do it.

Anonymous said...

I can't wait for the next one. I really appreciate your efforts.

Anonymous said...

The URL http://localhost:3000/movies is giving the following error after customizing the view (movies.html.erb) and creating exchange.css:

SyntaxError in Movies#index
compile error
~/exchange/app/views/layouts/movies.html.erb:14: syntax error, unexpected tCONSTANT, expecting kDO or '{' or '('
_erbout.concat "\t\t"; _erbout.concat(( @page_title || “Exchange Movies”).to_s); _erbout.concat "\n"
^



Not sure what's wrong here...I seem to have typed the same thing given in the tutorial though. Any help would be much appreciated. Thanks!

Anonymous said...

thank you very much :-)

Sean Lynch said...

Anonymous 12:08,

Please check line 13 and 14 in your /app/views/layouts/movies.html.erb

and compare with the following code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Exchange Movies: <%= controller.action_name %></title>
<%= stylesheet_link_tag 'exchange' %>
</head>
<body id="movie">
<div id="banner">
<%= image_tag("rails.png") %>
<%= @page_title || "Exchange Movies"%>
</div>
<div id="columns">
<div id= "side">
<h1> Sidebar </h1>
</div>
<div id="main">
<%= yield %>
</div>
</div>

</body>
</html>

Anonymous said...

Thanks a lot, Sean. I tried with the html code above and it worked for me.

While at it, I also wanted to let you know how much your tutorial is appreciated. All other tutorials I found on the web weren't working with Rails 2.0 and I was almost going to give up on Ruby on Rails! I'm glad I found your tutorial!

Adam said...

Great tutorial. I had trouble finding a good Rails 2.0 tutorial and I finally found one that actually works! Thanks!!

Sean Lynch said...

The scaffolding extensions plugin should give developers the ability to generate scaffolding as well as working with existing models.

It lists that it works with Rails 2.0 and can be installed as a gem.

Please follow this link for more details.

Anonymous said...

Like a lot of other people I have been struggling to find any good rails2.0 tutorials, much appreciated!

Anonymous said...

And I'm one more newbie who has struggled with other Rails books and tutorials, but made little progress until I found your tutorial.
Joe Cohen

Anonymous said...

Thank you very much!
Very good tutorial!
I'm waiting for the part 3 :)

Chris

shalini said...

awesome job!thanks.

shalini said...

awesome tutorial!thanks.

Anonymous said...

Great Tutorial!

Give me more ... :)

Anonymous said...

Very helpful. Thank you.

Anonymous said...

Kudos on the first usable tutorial I've found! My environment's a bit more complex as I use an Oracle DB and am working with an IDE (aptana studio) for RoR. It's pretty powerful once you get going, but it sure took me a while to get past the initial understanding of how it all goes together. Thanks for enlightening me.

Peace.

Darryl L. Pierce said...

Thank you. I've searched around and your tutorial is without a doubt the best for getting up and running with Rails 2.0. I anxiously await the next installment.

Olivier said...

As many people have already mentioned, thanks for posting a working tutorial. It's been really frustrating downloading Ruby on Rails and having none of the tutorials work. You've encouraged me to keep working on this because by getting something to work, I feel like I'm starting to understand how RoR works.

Obviously, I'm looking forward to the next installments.

Ed said...

Congratulation from Brazil !!!

Marcio said...

Thanks for the valuable information on this tutorial. An additional question though:

If I wanted to define two new classes DVD and VHS that were to inherit from movies, and in additional to the fields that belong to Movies, they implement their own fields, what are the steps involved on doing that ? Can anyone suggest some examples on inheritances?

Thanks,

--Marcio.

Guille said...

Amazing.. :)
A good way to upgrade

Anonymous said...

It Works!!
Thanks for all your hard work on this from a very New newbie!!

Anonymous said...

Hmmm,

Again thanks for this tutorial. Can't wait for part 3.

Tried this before & it worked now Everything is fine (links works & style is correct) however the images will not display. Actually, the rails logo displays fine but the movie images will not. I Right click and get the properties:

http://localhost:3000/images/BJ1.jpg

but it is different than the properties for the rails image (aside from the obvious name difference):

http://localhost:3000/images/rails.png?1202762355

Notice the "?1202762355" at the end.

Anyone have an idea of what's up?

Anonymous said...

Thank you very much for the tutorials. I am a rails newbie and was absolutely confused until now. I almost abandond rails before stumbling on this tutorial. thnaks again :)

Anonymous said...

Hey awesome tutorial. I've been trying to get my grip around this and you helped a lot. I would suggest one improvement: maybe in the end, add the CSS parts of the original scaffold.css to emphasize the error fields. Otherwise that error part doesn't work too well!

Good job.

RJS said...

Excellent tutorial Sean!

After creating _form.html.erb, I was receiving an error for the label_text variable while trying to edit or create a record. I changed the code to :label_text at line 17 and everything worked properly. Just thought I would pass that on in case it was tripping anyone up.

Keep up the great work!

RJS said...

Hey Sean,

Disregard my previous comment. I found my mistake. I had mispelled the label_text variable in the edit and new views, so I was referencing a variable that hadn't been created.

Thanks!

Anonymous said...

Thank you very much for your rails 2.0 tutorial. I'm baby on rails when I use some ebook to practice. I had error with scaffolding
and try to find some guide for my problem, then I find your tutorial. It help me much.

Thanks again.

Anonymous said...

Thank you a lot. For me, who is really a baby in the programming world, this tutorial is so wonderful..

Corey said...

hamrin, sean,
I too struggled to figure out why I wasn't seeing any out put for my yield. Turns out the problem was I had typed % yield % instead of %= yield %. Takes me back to when I was first learning c++ and I forgot my semicolons from time to time.

Thanks for the great tutorials.

Corey

Brandon said...

For our online-only Web Programming course, we had to implement a simple application using Rails 2.0. Three of us looked through 5 different resources over the course of 5 hours and, after much frustration, gave up, thinking Rails was ridiculously hard to use. Our problem was that we were using tutorials for older versions of Rails, not knowing there was a difference. Your tutorial not only saved our project, but what we couldn't accomplish in 5 hours, we can now accomplish in 5 minutes. Thanks :)

rob said...

awesome tutorial

thanx

Mike van Kuik said...

Hi Sean,

I must say great tut.
Just wondering... when is the next part comming out? :P
I'm a bit in a stub. now :D
Well I guess I'll be a bit further when you'll post part 3 ;) no prob.

I already found it great to be able to find a rails 2.0 tut. that works from head to tail :D .

tx again.

Mike van Kuik

Vinay said...

Take a bow Sean Lynch, Take a bow

fildawg said...

Thank you
Thank you
Thank you!!!

siko said...

Fantastic tutorial. Well done.

Anonymous said...

Thanks for this tutorial, I've been following some other side and there was a little bit confusion b/w code and version they represent. Here is clean cut. Awesome.

Anonymous said...

Thank you for your effort in making this tutorial as simple as possible to understand. Can you explain the procedure to add new table to database with a reference to the existing movie table.

EK said...

PLEASE POST PART 3!!! I'VE BEEN WAITING 4 MONTHS FOR IT!!!!

Sal B. said...

Thanks for this - been finding tutorials here and there for rails 2.x and it's coming along. I jumped into Rails just a few weeks ago and finding (good) tutorials for it is hard. Spent my 1st week in lynda.com only to (quickly) realize a lot of what he talks about is deprecated and made his videos hard to follow. Again, thank you for this and I hope to see more from you soon.

Anonymous said...

Hi, great tutorial!

I have this problem: the URL http://localhost:3000/movies is giving the following error after customizing the edit.html.erb with partials:

compile error
C:/RUBY/rails_apps/exchange/app/views/movies/edit.html.erb:6: syntax error, unexpected ':', expecting ')'
_erbout.concat " "; _erbout.concat(( render: partial => "form", :locals => { :f => f, :label_text => "Update"} ).to_s); _erbout.concat "\n"


Any suggestion?
Thanks

Frank Kuepper said...

@Anonymous: It's just a little typo in your edit.html.erb.

It should be render :partial and not render: partial

Anonymous said...

Thanks, Frank. Now it worked

metal said...

Thank you!! Exactly what i was looking! Greetings from Portugal!! :)

Anonymous said...

the tutorials i've been following are based on earlier versions of rails. can't get scaffold to run until now.

salamat!! (thank you) from the philippines!!!

Anonymous said...

the tutorials i've been following are based on earlier versions of rails. can't get scaffold to run until now.

salamat!! (thank you) from the philippines!!!

Anonymous said...

Dude, this article is awesome! It's stuff like this that is making Rails more used in general. The need for good tutorials is what it needs to get even bigger

I cant see why Im still programing stuff in Php... why bother when everything is so easy, fast and awesome in Rails - fantastic

YOU ROCK man!!! :Þ yeah!

Spencer said...

Thanks man - this was a great tutorial. As a .net guy looking to learn new skills and move to rails, you saved me!

Youmna said...

This tutorial is great!
I was looking for help with how to use release_at in my application and found this tut. I noticed that you're going to talk about this next time, when is it going to be?
Thanks!

amrita said...

I just started working with Rails and had spent hours trying to get my system to work using other tutorials. Your work is very nice, extremely systematic, and not at all cryptic for someone new to rails. Any chance you maintain an email list where you send out updates on this subject?

Thanks!

Eivind said...

Very good tutorial, easy to follow and very valuable to newcomers.

Why one earth does rubyonrails.org still host outdated tutorials anyway? Are they trying to shoot their own foot?

Anonymous said...

Thanks Sean for an excellent tutorials! I am new to ruby, followed your instructions and found success on the first try. I guess using the right tutorial version ie. rails 2 instead rails 1 helps too =) I am sold on RoR thanks to your tutorials.

have a great day! Greg.

Pradeep B V said...

Thanks

Anonymous said...

Thankx a lot for the tutorial, but we all missing really the next one when does it come?

Samuel said...

Thank you Sean for the great RoR 2.0 tutorial.
I was going nuts struggling with older tutorials that don't work with 2+.
This tutorial was great help and excellent / working example of how RoR works.

ahmet said...

Thank you for excellent tutorial.
These people like your way. Also, me. Please show us more example.

Anonymous said...

Everything has been said...
But as this great Tuorial saved me, I say it again : Many thanks !!

does someone knows how to génerate the scaffold command from an existing database?

Jim McGrath - Amateur Cyclist said...

Thank you! Great tutorial. I used your tutorial to create a pretty good looking prototype for a document image repository. Rails rocks!

John said...

Hi Sean.

Thanks for the tutorial. I have a small problem with the webpage. The text in the red rectangle doesn't show completely. (see http://jcoppens.com/misc/ror1.png).

It's not a big problem as I can get the code from the page source, but I've noticed this rendering problem before (even on the default page of RoR, the 'About your application' box gets rendered wrongly at times).

Is this a browser problem? (using FF 3.0.1 here)

Thanks again.
John

Luke said...

Thanks for the tutorial, it was a great help!

Jesse said...

Im so glad more rails 2 tutorials are coming up. Keep em coming! trying to learn rails is weird because most books are rails 1.xx :(

ramiz said...

very very nice tut.
thank you

Anonymous said...

Great tutorial but...

I can't see any pictures on the index page except for the rails.png logo??

I'm sure I've given the correct location for the pictures! I've even tried renaming them to .png files without success.

Please help

j.g. pawletko said...

I had the same problem (image URLs didn't seem to work when I copied them from the browser address bar). In Safari, you can copy the *image* address by right-clicking on the image and then paste this URL into the 'One sheet url' field when 'editing' a movie.

i.e., use :

http://3.bp.blogspot.com/_fnfsff2gWFY/R505SmK94hI/AAAAAAAAAMM/dpVMdc2_hnk/s1600/MITWS1.jpg

instead of:
http://bp2.blogger.com/_fnfsff2gWFY/R505SmK94hI/AAAAAAAAAMM/dpVMdc2_hnk/s1600-h/MITWS1.jpg


Sean - Thanks *very* much for a very helpful 2.0 tutorial!

best-

Anonymous said...

Very nice. I have been searching and found this and followed it very closely and found it to be usefull. Thanks.

Joe T. said...

Thank you for your great tutorial. Was going nuts trying to get the O'Reilly one to work.
Two Questions:
1. My side bar only goes part way, what determines in the stylesheet how far down it goes?

2. Am running WinXp with Apache 2.x, MySql 5.x, PHP 5.x. Would I just transport the exchange dir to get it to run on port 80 with Apache?

Again thanks for the sanity bailout.

Joe

Tom-el said...

This was very helpful, about the only place I found this info presented so clearly. Now, what about adding columns. If you can't use the dynamic scaffold, how do new columns get added to the scaffold?

Javier said...

woooh... this is great. Congratulations for this job from Argentina.

Disco Stru said...

Excellent tutorial. Thank God someone's put one out there for 2.0; I was going nuts with the older tutorials.

Thanks so much.

Anonymous said...

Thanks a lot!
I got it working...

Rob said...

A couple scaffolding questions:

1. Is there any way to build the scaffolding from a database connection (pre-existing table)?

2. Any way to build it from a pre-existing model (the ruby definition)?

3. How would I tell rails I want to generate scaffolding based on XYZ model but put the definition in ZYX controller?
(for example put the product model in the admin controller like the agile rails book specifies)

Thanks either way for the tutorial!

Tony Cavanna said...

Terrific tutorial for newbies. The first one I've been able to get through without problems. Looking forward to the next part. Hope it won't be too long coming.

Anonymous said...

Se agradece la información entregada debido a que me ha servido para poder comprender ROR. Soy nuevo en esto y este material es bastante práctico para principiantes.

Thanks so much.

Oscar HPN

Chris said...

Hey man,

this is a great tuorial and (as opposed to all the other stuff I tried so far) just works. Great stuff.

I hope part 3 is already in the works. :)

Keep up the good work and thanks ALOT!

GSouthall said...

Excellent ! thanks so much for your work.

I need to do some relational db work within your example, so if anyone knows any tutorials on this I'd be grateful for a lead.

Garfield Southall, Chester, UK

Marten said...

according man rails to specify a database use a capital d like rails -D sqlite3 project

Anonymous said...

While trying to learn Ruby on Rails 2, I found tutorials about Ruby on Rails 1.2 (not what I wanted), tutorials about updating from Ruby on Rails 1.2 to 2 (not what I wanted), tutorials about Ruby on Rails 2 (what I wanted), tutorials about installing Apache, MySQL, Ruby and Rails separately (not what I wanted) and all together (what I wanted), tutorials about installing on Linux (not what I wanted), Mac OS X (not what I wanted) and Windows (what I wanted). The tutorial with what I wanted and more is at:

http://www.sitepoint.com/article/learn-ruby-on-rails

BehanJ said...

In a word - Thanks.

This is possibly the best tutorial I have gone through for RoR (1or2).
You manage to put the ideas across in a very clear, concise manner. I've gone through several tutorials and I now have a much better understanding of partials, MVC, scaffolding and validation.
Thanks again, looking forward to part 3.

Anonymous said...

Agreed, this is by far the best ror 2.0 tutorial I've managed to find. Keep them coming!
-Patrick

Jim Hertzler said...

In the file index.html.erb
add "images/" to the line containing

"img class"

Now my images show up.

(I would like to be more specific but this
site will not allow me to paste in the source.)

Anonymous said...

Thanks for this quality tutorial ! ;)

Anonymous said...

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

that is the error i get... i have instead of movie i have final tho. I changed the words out, plural and all.... eric@ericlive.net please help.

sarah said...

Thank you so much for a great tutorial. I’m working through Four Days on Rails with Rails 2 ( http://www.ultrasaurus.com/code/2008/12/getting-started-with-rails.html ) and this tutorial helped a lot.

I would love to read more about controllers if you are inspired to write more.

Sarah

web designer said...

nice post

Anonymous said...

excellent post! drove through bunches of tutorials in books and couldn't get it up and running cause they were all for ruby 1.x. many thanks!

Anonymous said...

Dude,

This was awesome. Could you keep it up? I've wanted to learn this for a while now. This tutorial is the best thing I've come across to quickly learn to build a rails app.

Thank you.

Anonymous said...

Really really good tutorial!!!!!

Really looking forward to part 3!

Anonymous said...

I'll add my bump for part 3!!!!

komik oyun said...

This was awesome. Could you keep it up? I've wanted to learn this for a while now. This tutorial is the best thing I've come across to quickly learn to build a rails app.

giydirme oyunları said...

great article thanks

Anonymous said...

Great tutorial! I bouhght a book about Ruby and the rails but after reading this page I really understand the whole thing!

dpanupam said...

This is a very nice tutorials. Thanks. Web Designer

Popeye said...

Very nice. Just pure excellent!!!! Thanks.
I'm willing to pay for part 3.

Anonymous said...

Thanks for putting it online. very useful

Jesse Curry said...

Thanks for the tutorial, I really enjoyed having such an easy to follow introduction to RoR. I've had friends push me to learn RoR, but never really had the time. Now that I've seen how powerful it is I'm definitely going to learn more.

Anonymous said...

Thanks! Great work. Part III!

Anonymous said...

Best guide available cheers

Steven said...

Awsome tutorial !!

But i could not find Part 3 ... Am i missing something ?
;)

Thanks again

Kevin said...

Where is part 3?

tany said...

Great work dude keep it up. Tutorials are really very well compiled and easy to implement. Keep up the good work

Drammy said...

Excellent tutorials...

I second the call for part 3. Any news?

crasch said...

Great tutorials! Thanks for posting!

rprateek said...

very good and helpful tutorial for beginners. Good stuff !!

DeltaTango said...

Well done and a big thank you for an excellent tutorial. Your use of a stylesheet to the demonstration made a big difference.

Karen Zeller said...

Very nicely done tutorial; one of the better I have seen on any technical topic.

Worth mentioning on the images, that they only need to be referenced in the app as images/name.jpg.

Andrejs said...

Many thanks from absolutely newbie in Rails. I've tried many tuts before, but your is only I can complete from A to Z.
Thanks again.

Part 3..? Please...?

Anonymous said...

Nice article. Thanks for sharing nice information.
My Blog : earn money chao!

Anonymous said...

hi its very good tutorial to study for new developer

EJ said...

I followed your articles, especially the difference with 2.0 scaffolding. One question: Pre 2.0, the scaffold directive in the controller made an association between the controller and the table that was scaffolded. With cmd line scaffolding in 2.0, the scaffolding is created for the table, but it is has no association with the controller. In pre 2.0, putting the controller name in the URL would by default give a listing of the table referenced in the scaffold directive. But now, in 2.0, I have to put the name of the model/table into the url for the same result. So, how to link a controller to a scaffolded table in 2.0?

Sean Lynch said...

Dynamic scaffolding no longer works.
It is a one time scaffold generation.

scaffolding will not pick up changes automatically they must be made by hand post 2.0

EJ said...

Hi Sean,
Thanx for the reply. I understand that dynamic scaffolding is no longer supported. What I want to find out is if you can generate scaffolding via command line, but have the scaffolded table associated with a controller ( not dynamically, but routing wise ). In other words, I don't want the model as part of the url, but the controller, which would route to the index view for that table.

Alexandre Ferreira from Brazil. ;0) said...

Hi Sean,
It's a amazing tutorial. I had alredy a lot of other tutorial and spend very time without learn nothing.
Definitelly a did see the ROR did a good work!!!
Please, you must continue write about it!!!
Thanks for your help...

Anonymous said...

Hello, this is Chun, your tutorial is very helpful. I have 1 problem, when i create the _form.html.erb, and then new.html.erb, and edit.html.erb, after i finish all that, i get ��<�p�>� � � � , which can't finish your tutorial, do you know why it is happening? I use firefox. thank you for your response.

Anonymous said...

Hi, great work. I bookmarked the CSS stuff for later use as that was my next area of research. I have been coding in C,Perl and PHP for a long time and have been told to give RoR a try. Rather than a Hello World program or a library => book => subject tye of tut, I though I'd try it on one of my real systems. I have worked through miles of documentation regarding rake but I can't seem to find a way of doing something that I thought would have been simple. My existing database has over 100 tables abd I wanted to import that information into a Rails Object Model (scaffold?). I thought I nearly had it:

I have an existing mysql database and am trying to figure out how to import the existing schema.
Running 'script/generate model my_table_name' gives an incorrect migration file that just contains a timestamp like so:


class CreateEventCategories < ActiveRecord::Migration
def self.up
create_table :event_categories do |t|

t.timestamps
end
end

How do I get the table elements inside this do-hickey? Please don't tell me it is hand typed. RoR goes in the bin if that is the case. I hope not. It looks like it might be fun.

Cheers,
Mark Addinall.

Sean Lynch said...

Anonymous March 21,

type "script/generate model" at the command line in your application's top directory and the help file for the script/generate model command will be displayed. This includes the format of how to include column names and types in the command.

script/generate model ModelName [field:type, field:type]

Examples:
`./script/generate model account`

creates an Account model, test, fixture, and migration:
Model: app/models/account.rb
Test: test/unit/account_test.rb
Fixtures: test/fixtures/accounts.yml
Migration: db/migrate/XXX_add_accounts.rb

`./script/generate model post title:string body:text published:boolean`

creates a Post model with a string title, text body, and published flag.

So 'script/generate model my_table_name' creates your model (should use caps version here as example in help file hints) but no columns because you listed no columns.

There is probably a better way to do what you want to do as well. You have an existing schema. Rails migrations can execute SQL to run pure SQL.

For one idea look here:
http://www.justinball.com/2008/05/09/dump-an-existing-database-schema-into-a-ruby-on-rails-migration-ready-format/


Post to the ruby on rails talk group for more help:
http://groups.google.com/group/rubyonrails-talk/topics

-sean

Steve said...

Take a look at the Magic Model Generator, which will generate models based on your existing tables.

http://magicmodels.rubyforge.org/magic_model_generator/

Anonymous said...

Thank you very much, I was getting soo frustrated with other Rails tutorials not working. Then discovered the problem was due to rails 2.0. Your tutorial was well written and easy to follow, seeing results the stopped me from giving up on RoR. Thanks. Im looking forward to Part3.

R. Azimi said...

Thank you ... excellent job ...

L5n25 said...

Thank you. I had sometime ago ventured into Rails (1.0) and was dismayed that Rails 2 had "moved my cheese". But your tutorial updated my knowledge in short order and enhanced my understanding. Thanks again!

diva said...

wow nice blog because i'm a newbie and i need some info to use rails..
tahnks.

jasonperr said...

By far the best ROR tutorial out there. One that ACUTALY WORKS!!! I'm amazed and so happy I found it. Please tell me more!

-- Jason

iPad Application Development said...

Great. I am sure, I will tweet this to my twitter account. This will help a lot of users.

Alexandre said...

I had read the tow tutorials, and they are very well writen, congratulations for the great work! Can't wait to the 3rd one! Thanks!

mario oyunu said...

I though I'd try it on one of my real systems. I have worked through miles of documentation regarding rake but I can't seem to find a way of doing something that I thought would have been simple. My existing database has over 100 tables

giydirme oyunları said...

I have an existing mysql database and am trying to figure out how to import the existing schema.
Running 'script/generate model my_table_name' gives an incorrect migration file that just contains a timestamp like so:

mario oyunları said...

very good and helpful tutorial for beginners. Good stuff !!

mostwood said...

Great tutorial and plenty of room to play! I did have a problem with the display of the jpegs on the main page running Firefox 3.6.10 on Win 7 64 bit. I ended up substituting the use of image_tag for <img in index.html.erb:

<%= image_tag(movie.one_sheet_url, :size => "54x70") %>
<!--img class="list-one-sheet" src="<%= movie.one_sheet_url %>"/-->

The 54x70 worked better for my jpegs and this bypasses the css but it solved the problem for me.

Thanks again for your work!

hugo oyunları said...

I have worked through miles of documentation regarding rake but I can't seem to find a way of doing something

kayu oyunları said...

I was getting soo frustrated with other Rails tutorials not working. Then discovered the problem was due to rails 2.0. Your tutorial was well written and easy to follow, seeing results the stopped me from giving up on RoR.

balon patlatma said...

Pretty good list, I’m just glad it’s concise.

Salman ansari said...

nice tutorials for beginner.
Thanks

suketa sharma said...

Can you please help me out, as I have to store all the data in a table to another table whenever I desstroy its ID....