Choosing an IDE or Editor
I have downloaded the RubyMine from Jetbrains who are the makers of famous ReSharper for .NET guys and IntelliJ for Java. I generally like the products of Jetbrains but I see RubyMine is still in its early stages and not free. You may still download the product and try it for 30 days.
Frankly, I see RubyMine tries to do a lot, download bundles run rails, use any rails generators but since we are in the learning stages and understanding under the hood, it is better to go with a basic normal editor.
The editor I am going to use is BlueFish which I mentioned before. BlueFish is a very nice simple editor which makes it easy to browse folders, create files, and also nice syntax highlighting for different languages ( html , javascript , java , ruby , PHP, PERL , Python )
Folder tree is refreshed automatically if you click one time to the folder ( wow! ) It is very handy if you use rails through command line!
New Rails project
Lets start with writing code. First of all we need to create a new rails application. In order to do that open up a console and run the following command
rails new demo1
creates a new demo1 project. The project is empty which means there are no mappers, controllers or views are created for you. New command only generates a basic Rails project structure.
Mapper
config/routes.rb here you define a new route for the request handling
- open up the config/routes.rb
- Go to line 51
-
root :to => "home#index"
- uncomment the root and change the string with home#index
Basically with this piece of code we tell rack that we will have a home controller and in that home controller there will be method called index. Lets create that controller first
- go to app/controllers
- add a new file called home_controller.rb
- in that file place the following line of code
class HomeController < ApplicationController
def index
@message = " Hello from the home controller"
end
end
We don’t want to place any html inside the controller, so let’s create our view as well. The file extension of the html file will be .erb which stands for eRuby that is the ruby templating file like asp or jsp
- go to app/views/
- create a folder called home
- create a file named index.html.erb
- and place the following code.
It is important to understand that all the files and code placed inside is a convention.
- home_controller.rb maps with root :to => "home#index"
- and the class
- HomeController maps with root :to => "home#index"
- def index maps with root :to => "home#index" and index.html.erb as well
To try how things will be broken, just rename one of the following into “homex” and see the errors.
If you place everything fire up rails in console using
rails s
in your application directory.
Using Query Strings
Make a request to your home http://localhost:3000/?m=testtest Rails contains an object called params and to get the value of the m query string
@user_messsage = params [ :m ]
Open your index.html.erb to modify the html and print out the parameter that passed in ( which is a bad idea to directly output the value )
<h1> <%=@message%> & <%=@user_message%> </h1>
and if you refresh you browser you will see
Hello from the home controller & testtest
but if you pass in an html tag with your query string , Rails 3 will automatically encode the output http://localhost:3000/?m=testtest<h2>
Forms
Create a form and post the information to server and back Create a new file called new.index.erb under your views/home folder paste the following code ( normal way, not rails way! )
<form action="/home/create" action="post">
<input name="message" />
<input type="submit" value="submit" />
</form>
and we need to map this action in our routes file.
Routing Error
No route matches "/home/create"
Routing
Rather than mapping all the actions one by one, we may remove ( comment ) the match line and active the line 57
match ':controller(/:action(/:id(.:format)))'
which will do the auto mapping for us. ( sounds familiar with ASP.NET MVC global.asax routing definitions ? :)
We previously define basic html to post our data to the server, but in rails you don’t need to write that piece of code.
<% form_tag ( 'create' ) do %>
<input name="message" />
<input type="submit" value="submit" />
<% end %>
navigate to http://localhost:3000/home/new
def create
@message = params[:message]
# new in Rails 3 build in, use notice
redirect_to "/" , :notice => @message
end
and refactor index.html.erb into
<h1>
<%=@message%>
</h1>
<%=notice%>
as you realized, we did not use the @user_message but use the notice session parameter which we set in the create method
CRUD
So far we went with the basics but the real power of rails starts with database operations and how easy to manage, generate and iterate. We start with the rails generator Scaffold
rails g scaffold pint name:string price:decimal
This will tell the rails that, hey rails
- I want have a new model called pint
- Pint will have two fields which are
- Name is a string
- Price is a decimal field
Rails does not like singular form of models ( like pint in this scenario ) Here is the output rails 3 generates
bahadir@ubox:~/RubymineProjects/demo1$ rails g scaffold pint name:string price:decimal
invoke active_record
create db/migrate/20110206113538_create_pints.rb
create app/models/pint.rb
invoke test_unit
create test/unit/pint_test.rb
create test/fixtures/pints.yml
route resources :pints
invoke scaffold_controller
create app/controllers/pints_controller.rb
invoke erb
create app/views/pints
create app/views/pints/index.html.erb
create app/views/pints/edit.html.erb
create app/views/pints/show.html.erb
create app/views/pints/new.html.erb
create app/views/pints/_form.html.erb
invoke test_unit
create test/functional/pints_controller_test.rb
invoke helper
create app/helpers/pints_helper.rb
invoke test_unit
create test/unit/helpers/pints_helper_test.rb
invoke stylesheets
create public/stylesheets/scaffold.css
After that check out the folders in your folder structure. Let’s migrate the database so that our model is also reflected ( huh did we have already a database setup ? :) Well, Sqlite is already in place and rails already made the setup for us.
rake db:migrate
bahadir@ubox:~/RubymineProjects/demo1$ rake db:migrate
(in /home/bahadir/RubymineProjects/demo1)
== CreatePints: migrating ====================================================
-- create_table(:pints)
-> 0.0018s
== CreatePints: migrated (0.0019s) ===========================================
I am amazed how easy it is! Hold on a second, we did not setup any routing and application responds us. How could it be happen ? Open up routes.rb file Line 2 is added by the rails generator
resources :pints
which does the all the routing tricks for us.
d866cb5f-7783-4ab2-960b-f25da78bfca6|1|5.0