Archive for August, 2009

Updating Ruby / Rails

Updating Ruby, Rails and other installed gems is pretty easy.

1 – Run the command “gem outdated”, to see which of your installed gems need updating.

2 – Update the gems itself by running

gem update --system

3 – Then if you want to update all the gems, simply run the command “gem update”. If you’re running the command in Windows, you should probably run “gem update > result.txt”, which will output the results of the command in the text file, so that you can take a look if any error were reported in the process.

4 – Finally, if you made an update of Rails, you will need to manually change the version your project uses by going into config/environment.rb and finding and changing this line:

RAILS_GEM_VERSION = '2.3.3' unless defined? RAILS_GEM_VERSION
Advertisements

August 30, 2009 at 3:45 pm 4 comments

Code refactoring: generic partials

When making project of any size you will most probably find yourself repeating code from one model in the other, be it similarities in models, controllers or views. This time I would like to explain how you can take out any repeated code in your views by using partials.

In order to call a partial from your view, you will need to use a render(:partial) method, like this:

<%= render :partial => "common/tags", :locals => { :thing => @artist } %>

1 – So, “common/tags” tells Rails to look for your partial called _tags.html.erb (remember the underscore in front – this is an easy visual way to say that the view template is a partial) in directory app/views/common.

2 – The :locals hash sends all needed variables to the partial. In our case we are sending @artist variable as a local variable called thing. You can send as many local variables as you need.

Now, let’s look at the partial:

_tags.html.erb:

	 <b>Tags:</b>
	 <% thing.tags.uniq.each do |tag|%>
	 <%= link_to tag.name.capitalize, tag_path(tag.name) %>
	 <% end %>
	 <%= link_to "Add more tags", edit_polymorphic_path(thing) %>
     <% end %>

1 – You see that the partial works with whatever the view passed to it in the local thing variable. As it’s a local variable there is no @ in front.
2 – As the partial does not really know what thing really is (and doesn’t need to in our case, apart from the fact that the thing should have tags method), if you want to include links in the partials, there are some easy to use methods for you:

link_to "Show this thing to me", thing
link_to "Edit this thing", edit_polymorphic_path(thing)

1 – The first notation is very useful short form of link_to – you can pass whatever object in place of the link and Rails will generate the right link to this object’s show method (it works with RESTful resources).

2 – The second is the same but for editing any object. Just use edit_polymorphic_path(thing). It will create an edit path for your object automatically. You can read more about polymorphic routes here.

So, this way you can make your partials generic and not dependent on the type of object being passed to it. If you will need to know what the thing being passed really is an object of, you can always check the thing.class.name property, which will return a string with the name of its class. But if you need to branch your code based on class of the object passed, you might not need to move it to a partial in the first place.

August 30, 2009 at 3:10 pm Leave a comment

Best Resources for Rails

These sites are extremely helpful for anybody starting out with Ruby on Rails:

1 – Rails API. A must for getting any information about Rails methods, etc. Can be a bit overwhelming for a total newbie, but becomes vital for any intermediate developer. Sometimes the descriptions are not detailed enough or do not provide enough examples to “get it”, so additional search in google may be in order 😉

2 – Ruby Docs. Unofrtunately Rails API doesn’t include the Ruby methods and classes descriptions, so you sort of need to move between the two, if you don’t remember if include? is a method of Rails or Ruby.

3 – Stackoverflow. A really great resource for quickly getting your questions answered or searching for a solution to a problem. Some of the very experienced Rails guys give free and valuable advice there, highly recommended!

4 – Rails Forum. A good resource for searching solutions for encountered problems. Some questions do not get answered though :(.

5 – Railscasts. Great free short video tutorials on many, many topics. The pace, level of detail, comprehensibility are all top-notch, you should spend as much free time watching those as possible 😉

Hope it helps. Do include additional suggestions in the comments to share with others

August 21, 2009 at 10:41 pm 4 comments

Yet more advice on learning Ruby & Rails

A good post on the official Ruby on Rails blog goes through advice of the Ruby development team on how to start learning Ruby.

August 16, 2009 at 11:45 am Leave a comment

5 minute project in Rails

Ok, you’ve installed the Ruby on Rails and you want to run a quick tutorial to see what can be done. Let’s do a simplified Journal application that allows to create users & posts.

1. Create a new rails project by running a rails name_of_the_project command, like this:

rails journal

You will see a bunch of “Created xxx” messages, that will create or copy over a bunch of directories and files.

2. Next, let’s create a Scaffold for our users. Scaffold is a basic structure of Model, View and Controller that allows you to quickly create, edit, show and delete objects. Let’s assume that each user will have a name, a biography and email for now. We will use a generate script in order to automatically prepare all required files for us. Here’s the command:

ruby script/generate scaffold user name:string bio:text email:string

3. So, in the step before we have created a User model, user controller and user views for each of the basic functions of create, edit, show and delete.

The model now consists of three attributes which will be recorded in the database columns, named name, bio and email. In your Rails code you will access those attributes by something like @user.name, @user.bio or @user.email.

However, the generate script does not create the model in the database, it just creates the migration file in the db/migrate folder of your project. You can check out the directory to see that a file create_users.rb (with a timestamp in front) is actually there. If you will need to extend the model later, it can easily be done by running another migration.

Ok, let’s run the migration by typing the command:

rake db:migrate

4. Now, run the server to check that everything works as expected:

ruby script/server

And try out the following address: http://127.0.0.1:3000/users

It should show you an interface to create / edit / delete users

5. Let’s then create a model for our posts. Here’s the same command we used for creating users:

ruby script/generate scaffold post title:string post:text

And, as before, you need to modify the database by running a migration:

rake db:migrate

6. Now, we want to be able to merge these two models together. What we want to say is that a User can write (have) many posts and each post has to be written by a (belong to) user. This is very simply done in the model definitions:

In app/models/user.rb add has_many :posts association

class User < ActiveRecord::Base
 has_many :posts
end
&#91;/sourcecode&#93;

In app/models/post.rb add belongs_to line:
&#91;sourcecode language='ruby'&#93;
class Post < ActiveRecord::Base
 belongs_to :user
end
&#91;/sourcecode&#93;

Now Rails knows that Posts and Users are related and you should be able to get a list of posts of a particular user by simply typing @user.posts and vice versa - an author of the post will be @post.user. This is really cool!

Before it all works, however, you need to provide Rails with a place in the database to store the relationship. It's done by including the id of user to the Post model (you don't need to store / modify anything in the User model). The notation Rails follows is &#91;related_model_name&#93;_id, in our case user_id. And then Rails will be able to do all the wonderful relationships. 

You can use the already used generate script, but this time a command migration will be used:
&#91;sourcecode language='ruby'&#93;
ruby script/generate migration add_user_id_to_post user_id:integer
&#91;/sourcecode&#93;
And run the migration again (you should start to get used to that command by now):
&#91;sourcecode language='ruby'&#93;
rake db:migrate
&#91;/sourcecode&#93;

7. Now it's time to modify our default views to take advantage of the new relationship. First, let's show the author's name of the post. Go to app/views/posts/show.html.erb and add lines 6-9 to it.

&#91;sourcecode language='ruby'&#93;
<p>
  <b>Title:</b>
  <%=h @post.title %>
</p>

<p>
<b>User:</b>
<%= link_to @post.user.name, @post.user %>
</p>

<p>
  <b>Post:</b>
  <%=h @post.post %>
</p>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

Let’s analyze what this command does – link_to @post.user.name, @post.user

First, I already mentioned that you can get the author by accessing @post.user. @post.user is actually an instance of user and you can access any attributes of user, so in order to get the name of the user you write @post.user.name. link_to is a clever method that allows you to create a link to a controller or object. The first parameter is the title of the link, the second is the url. As link_to is a smart method, you can simply pass an instance of a class to it and it will figure out how to link to it.

8. Now, let’s show all posts of a user when you show a user. For that we need to modify the user’s show view (app/views/users/show.html.erb), adding lines 16-23:

<p>
  <b>Name:</b>
  <%=h @user.name %>
</p>

<p>
  <b>Bio:</b>
  <%=h @user.bio %>
</p>

<p>
  <b>Email:</b>
  <%=h @user.email %>
</p>

<p>
  <b>Posts:</b>
  
  <% @user.posts.each do |post| %>
    Post: <%= link_to post.title, post %><br/>
  <% end %>
  <%= link_to "Create new post", new_post_path %> 
</p>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

Ok, this one took 4 non-HTML lines, let’s go one by one:

@user.posts.each do |post| — we access the array of user’s posts and iterate through each of them by using iterator each. each is the easiest way to go through all the object in an array. The iteration passes control to block and puts each element one by one of array in local variable post.

link_to post.title, post — this is almost the same as we did for post’s user earlier.

end – this is to say to Rails that it’s the end of the iteration block

link_to “Create new post”, new_post_path — By this line we allow a new post to be created. First parameter is the string for a name of the link, second – is again a cool way to link to action of a controller [action]_[controller]_path

9. Finally, when we create a new Post we need to be able to select who is the author of the post by selecting the author from the list of available authors. In app/views/posts/new.html.erb before the lines <p> <%= f.submit ‘Create’ %> insert the new field:

  <p>
    <%= f.label :user_id %><br />
    <%= f.collection_select(:user_id, User.find(:all), :id, :name, {:prompt => true}) %> </p>
  </p>

The first line simply creates a text label of the field. The second creates a drop down list of all users in your system. The most important are the first 2 parameters – :user_id, which tells the form which variable to store the result of selection in and User.find(:all), which provides a list of all users to the drop-down.

10. Now save all changes and run the application at http://127.0.0.1:3000/users

This is an impressive application given that it took you only 5 minutes, 15 lines of code and couple of command-line commands. Of course, you will need to extend it with a proper user authentication and you will want to modify models and views to make the app useful, but it’s a great start.

August 8, 2009 at 8:43 pm 22 comments

Ruby on Rails screencast / course

If you haven’t seen it yet, a good way to start off with Ruby on Rails is this Berkeley screencast / course. It’s pretty long, so make a cup of tea / coffee and get comfortable.

There are 4 parts of the course, the 1st is a (very basic) intro to web development and Rails and the guy must have drunk way to much coffee ;), the 2nd is an introduction to Ruby, which sometimes goes way too deep into peculiarities of the language for the beginners, but is still a useful intro, the 3rd,4th go back to Rails.

Part 1 – Intro to Rails

Part 2 – Intro to Ruby

Part 3 – More Rails

Part 4 – Rails Active Record

August 8, 2009 at 6:03 pm 1 comment


Recent posts

Starting to learn Rails?

Kindle

Get Kindle - the best e-book reader, that I personally use, and the only one that you can read on the beach - very useful: Kindle Wireless Reading Device (6" Display, Global Wireless, Latest Generation)