Workbook

From mi-linux
Jump to navigationJump to search

XML and Web Services >> Workbook

Ruby install on a USB stick

  1. Download the One-click ruby installer from rubyforge http://rubyforge.org/frs/?group_id=167 (warning this is a big file!). The one I used was ruby186-25.exe but there may be a later version available. To be able to run the whole environment from a USB stick I’d really recommend you have about 500MB free (maybe it’s time to buy a new stick?)
  2. Double-click on the installer, after clicking next a few times, a screen like the one shown below is displayed.
    Workbook01.gif
  3. Ensure you install on your USB stick, not the C drive (check the drive letter, as shown. Mine is J:, yours may vary)
  4. Once Ruby is installed, open a cmd prompt (enter cmd into the ‘run’ box from the start menu) change to your ruby directory (e.g. j:\ruby ) and enter the follow command:
  5. gem install rails -y
  6. You may need to add the ruby directory to your system path, the setenv.bat file discussed in class will do this – the command is:
  7. set path=%PATH%;j:\ruby\bin;
    1. Remember to change the drive letter (j: in the example above) to match the letter assigned to your USB stick. This will probably be different for each system – it’s a windows foible – what a wonderful system :) (maybe you should try Linux? – ok Rant over.) This is why we suggested in the lecture that you put the command above in its own file, which we called setenv.bat, so that it’s easy to change.
  8. The gem command should install rails, see below for a database.

Exercises

Create one (or more) programs using ruby that can perform the following tasks:

  1. Create a program that can take a phrase as input and print it out in reverse.
  2. Create a program that can take a phrase as input and output it’s length as a number
  3. Create an application that can encrypt any phrase you enter using the rot13 algorithm
  4. Create an application that can take a temperature in F or C and convert to the other form

SQLite install on Windows

  1. Download the sqlite package from http://sqlite.org/download.html (you will need a file called sqlitedll-3_x_y.zip where x and y are numbers (they change, unfortunately). For reference I used sqlitedll-3_3_17.zip when I downloaded it. The download page is shown below:
    Workbook02.gif
  2. When you have downloaded the file, unzip it and extract it to a directory called sqlite on your usb stick (you may need to create this directory first.) You should then copy the sqlite3.dll file to your ruby\bin directory.
  3. Next use the gem command again to install the ruby-sqlite bindings so that ruby can use sqlite. The command is given below:
  4. gem install sqlite3-ruby (choose option 1 from the menu)
  5. Rails apps should be stored in their own directory – I tend to call it railsapps. Create this directory on your usb stick
  6. To test that rails is working properly type the following commands:
    1. cd railsapps
    2. rails mytest --database=sqlite3
    3. cd mytest
    4. ruby script/server
  7. Now start IE (ugh!?!?) or Firefox (yep!) and enter localhost:3000 into the URL bar, you should see the screen below. If not, try entering http://localhost:3000/ instead.
    Workbook03.gif

- EDIT

To run your ruby on the mi-linux server first connect to it through putty then use;

   ruby script/server -p <YOUR PORT>

This will start your server running externally on the mi-linux server (required for module)

This should then accessible from

  http://mi-linux.wlv.ac.uk:<YOUR PORT>/

In order to shutdown your instance of Ruby;

   kill -9 <PID>

where PID is your process ID, obtainable by the command

  ps ux

--0623815 11:48, 13 March 2008 (UTC)

MVC & Controllers

  1. Using the instructions given above, create a new application called myapp, connected to a sqlite database, and cd into the directory.
  2. Create a controller using ruby script/generate controller Say
  3. cd into the app\controllers directory and open the say_controller.rb skeleton.
  4. Add the hello class as shown below:
    Workbook04.gif
  5. Create a new view template in the app\views\say directory, called hello.rhtml
  6. Code is given below:
    Workbook05.gif
  7. Test the above, what do you see? (http://localhost:3000/say/hello - don't forget to start server again 'ruby script/server')
  8. Add a goodbye method to the say controller using the instructions above.
  9. Create a goodbye view to accompany the goodbye method, but change the message to “see you later”
  10. Modify the hello view to have a link to the goodbye view, example below:
    Workbook06.gif
  11. What does the h helper do?

Here are a few bits of info I found on the 'h' helper:

The 'h' in the '< % = h...% >' is there to strip any unwanted html.

You won’t find the definition for the h() helper function anywhere in the Rails source code, because it’s a shortcut for ERb’s built-in helper function html_escape().

The h() helper function converts the following characters into their HTML entity equivalents: ampersand (&), double quote (“), left angle bracket (<), and right angle bracket (>).

Passes a string of data into the h() helper function to escape its HTML entities.

--0621651 17:16, 19 March 2008 (UTC)

  1. Create a link from goodbye back to hello
  2. Investigate the formatting options/helpers available to make the time display more manageable.

Models and ORM

UPDATE: this has changed in Rails 2.0!! If you are using the latest version of rails do the following:

- create a model at the same time you scaffold by (for example) 
- ruby script/generate scaffold student name:string s_no:integer course:string 

This creates a model called student (and by convention a db table called students) with a name of type string, a s_no that is an integer and a course that is a string. Before you can use this model - you need to create the table, this you do by running rake db:migrate If all is successful when you next run your application you will have 4 pages created automatically to create, edit, update and destroy the contents of your model/db!

  1. Start the application with ruby script/server, start a browser (firefox?) and navigate to http://localhost:3000/students (based on the example above)
  2. Add some data by clicking on ‘new student’ and filling in the boxes that are displayed – remember to click ‘create’ after each entry.
  3. What happens if you leave any field blank? Is this what you require?
  4. You can add validation by editing the ruby file that wraps the database – in this case student.rb – found at K:\Documents\railsapps\myapp\app\models\student.rb. Edit this file to read as below:
    Workbook08.gif

(EDIT) - IMAGE ATTACHED TO REFLECT WHAT IS WRITTEN IN INSTRUCTIONS

08 fix.gif
  1. Create a new entry, but leave the stud_no and course fields blank. What happens? Is this a useful function?
  2. Experiment with the validation helpers to see if you can ensure that the student number lies within a certain range.

Views & templates

  1. Create a controller called info using the ruby script command (see above). Edit the file to be as below:
    Workbook09.gif
  2. This code retrieves the student info from your database and stores it in a hash called students (the @ represents an instance variable, which keeps a classes state). This will allow us to use the data in a view.
  3. Next create a new view with the extension rxml – this tells rails it is a ‘builder’ class and it will automatically associate it with the builder library. Builder allows you to use ruby code to create xml files. Call the file stulist.rxml (to associate it with the controller we have already) and edit it to contain the following
    Workbook10.gif
  4. This will create an xml file as shown below (depending on the data stored):
    Workbook11.gif

Rails and testing

  • Rails provides a unit testing framework (actually it uses a ruby one called Test::Unit). To protect the development and production environments it uses a separate db for testing. However, as before Rails cannot create a db directly, fortunately rake can.
  • Type rake db:test:prepare at the command prompt.
  • Note that rails has created a test skeleton suite under the test directory, as discussed in the lecture unit tests test models, functional tests test controllers, and integration tests test flow through one or more controllers. This exercise will concentrate on unit tests, the others are left as (essential) exercises for the student.
  • If we type ruby test\unit\member_test.rb (assuming we are in our application directory and we have a file called member_test.rb in the unit directory) we should see


Workbook12.gif


  • If you examine this file you will see it is essentially empty, however even this test demonstrates that our test db is set up and it has a schema that echoes our model (i.e. it has the right tables)
  • We can test our validation as follows: - edit the test program to include a new member, as shown below


Workbook13.gif


  • If you run the test program what happens? You should get an output as below. Is this what you expected? Why?


Workbook14.gif


  • Now edit the test program and make the mem_id empty (i.e. “”). Now run the test again. What happens this time?
  • You can enter data directly into the test program, or you can use fixtures.
  • Open the fixtures file in the test\fixtures directory (mine is called members.yml, yours may be different). A screenshot is given below:


Workbook15.gif


  • Note that it already has data, and it is valid data too..

Simple Ajax 'Live Search'

This uses the observe_field helper, which is part of the prototype helper library. It is based on a very simple model, with a single controller – the controller should be able to be integrated with your existing application. This is based on an example given in Rails Cookbook by Rob Orsini, but it is very similar to the example in Agile Web development as well.

  • Create new application (Rails bookstore)
  • Create a model (ruby script/generate model Book)
  • Create a controller (ruby script/generate controller books)
  • Edit the migrate script found in app/db/migrate to be as shown below
 class CreateBooks < ActiveRecord::Migration
   def self.up
     create_table :books do |t|
     t.column :title, :string
       t.timestamps
     end
  
     Book.create :title => 'Best practice'
     Book.create :title => 'Worst practice'
     Book.create :title => 'Bling examples'
     Book.create :title => 'Best goals'
     Book.create :title => 'Best cars for under 100 quid' 
     Book.create :title => 'Worst Drivers ever '
     Book.create :title => 'Working cars'
     Book.create :title => 'Worst deals for under 100 quid'
     Book.create :title => 'Better deals'
   end
  
   def self.down
     drop_table :books
   end
 end

(you can change book titles if you like!)

  • Create a layout (html file) in the views/layouts folder called books.rhtml. File contents shown below:
 <!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>BOOKS</title>
     <%= stylesheet_link_tag 'scaffold' %>
     <%= javascript_include_tag :defaults %>
   </head>
   <body>
     <%= flash[:notice] %>
     <% image_tag 'loading.gif', :id=>'spinner', :style=>"display:none; float:right;" %>
     <%= yield  %>
   </body>
 </html>
  • Edit the controller (books_controller.rb) to have the content shown below:
 class BooksController < ApplicationController
 
   def index
   end
 	
   def get_results
     if request.xhr?
       if params['search_text'].strip.length > 0
         terms = params['search_text'].split.collect do |word|
         "%#{word.downcase}%"
       end
       @books = Book.find(
         :all,
         :conditions => [
         (["(LOWER(title) LIKE ?)"] * terms.size ).join(" AND "),
         * terms.flatten
         ]
         )
         end
       render :partial => "search"
     else 
       redirect_to :action => "index"
     end
   end
 end
  • Create an index view (index.rhtml) in the books folder of views as below:
 <h1>Book Search</h1>
 
 Search: <input type="text" id="search_form" name="search" />
 
 <img id="spinner" src="/images/loading.gif" style="display: none;" />
 
 <div id='results'></div>
 
 <%= observe_field 'search_form',
 				   :frequency => 0.5,
 				   :update 	  => 'results',
 				   :url       => {:controller=>'books', :action=> 'get_results'},
 				   :with      => "'search_text=' + escape(value)",
 				   :loading   => "document.getElementById('spinner').style.display='inline'",
 				   :loaded    => "document.getElementById('spinner').style.display='none'"  %>
  • Finally create a ‘partial’ that implements the actual search: ( this is called _search.rhtml and is stored in the views/books folder again:
  <% if @books %>
    <ul>
      <% for book in @books %>
        <li>
          <%= h(book.title) %>
        </li>
      <% end %>
    </ul>
  <% end %>	
  • This method for displaying data is very simple yet if you need to show multiple bits of information for your search you can use a table. You can find how to do this by looking at the scaffold created index pages in your rails app.

That’s all – run your new application and watch the live search – note not a line of javascript in sight – the power of rails!

XML

Please look at the following tutorial : https://www6.software.ibm.com/developerworks/education/x-rubyonrailsxml/x-rubyonrailsxml-a4.pdf

Tips & tricks

Please add to this as you find interesting or useful things

Using the Amazon API If anyone has considered having an Amazon search on their site then you'll need to work with the Amazon web services API (http://www.amazon.com/gp/browse.html?node=3435361). After a couple of days messing around (and swearing) I've found two solutions to using the Amazon API with rails. The first is to use a library called Ruby/Amazon (http://www.caliban.org/ruby/ruby-amazon.shtml), this is definitely the easiest option, however you need to install Ruby/Amazon on the server which means it cannot be used on the student servers (mi-linux). If your doing your demo off of a USB drive though this shouldn't be a problem and as I've said Ruby/Amazon is incredibly easy to use, a quick google search came with these two articles which should get you started:

http://www.ddj.com/showArticle.jhtml?articleID=184405959

http://www.roryhansen.ca/2005/07/18/amazon-web-services-on-rails/

The other option is more complicated and involves the use of javascript. At first I thought it would be possible to access the API using javascript and the XMLHttpRequest object, but it turns out that using XMLHttpRequest with external URL's throws up security issues. However I found a site that talks about using JSON (JavaScript Object Notation) and XSLT to grab data from the Amazon website without the need for external libraries or the XMLHttpRequest object. This solution is more complex though and requires you to have a basic understanding of what JSON and XSLT are about, however with the examples provided on the site it is a feasible option.

Link - http://www.kokogiak.com/gedankengang/2006/05/consuming-amazons-web-api-directly.html

--0602510 14:33, 20 March 2008 (UTC)

Working with sessions

Hey guys, just a few tips if you want to work with sessions (Useful for logging in, shop cart, etc.). A session can be instantiated or changed simply by using session[:user] = "my username", or you can create a session from a submitted form using session[:user] = params[:user}, particularly useful for logging in, if you want to check to see if a session exists, you can simply use:

if session[:somesession]
  #do something really great with the session
else
  #explode your computer
end

The easiest way I found to destroy a session (e.g. logout/clear cart) is to set the session to nil:

session[:somesession] = nil

There are other methods to do the above but they caused exceptions for me in general usage. Session have more than one dimension, so if you do decide, you could have session[:user][:name] = "Danny" and session[:user][:age] = "21", if you pass params[] from a form, you will have to use this to retrieve the information --0601163 02:17, 17 March 2008 (UTC)


This page is useful in determining what should go where is Rails crazy dir/folder structure http://www.slash7.com/articles/2005/3/6/rails-what-goes-where

To run your application on the student server you will need to change the port number to something other than 3000. I will assign new numbers next week, but a guide on how to do this is at http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/180461

Useful links for rails 2.0? Found these on a forum site, haven't tried them - it would be useful if some of you gave them a go and let the others know how they went. Link: http://railsforum.com/viewtopic.php?id=15794

Rails Screencasts Check out Ryan Bates' Railscasts.com for some (seemingly) useful Rails screencasts. I have checked out a couple of these and they seem to be quite useful as you can watch what he types while listening to the explanation. Link: http://railscasts.com

Animated Loading GIF: A site that will create a nice little animated GIF to use as a loading image (as used for the AJAX live search above). Different styles and colours are available. When you have created the GIF, all you have to do is save it into your apps public/images folder and insert it into your code. Link: http://www.ajaxload.info/


Useful websites

This website has a good tutorial for ruby on rails and shows many things such as how to put css into your rails site, how to add a bit of AJAX, how to make a upload feature in your site and explains about sending emails in rails. It also explains areas of rails such as views, controllers and migrations so you can gain a better understanding. Link: http://www.tutorialspoint.com/ruby-on-rails/index.htm

Forum

Many of you many want a forum in your site, I have come across several that many be suitable but you will be required to learn about subversioning for some of them.

Beast (ruby forum built in under 500 lines of code) Link: http://beast.caboo.se/ This site should help with installing beast : http://www.olddognewtricks.co.uk/2006/09/beast.html

Savage beast, a variation of beast : http://www.williambharding.com/blog/?p=100

El Dorado, a forum for ruby based on punBB: http://almosteffortless.com/eldorado/

Wiki

You many want to have a wiki and here is a tutorial for creating one in rails, you may not be able to use the downloadable one as it uses an older version of rails. Link: http://www.devx.com/webdev/Article/34200#codeitemarea

Here is another tutorial to building a wiki, it takes you through all the steps showing command line and view screenshots of the process. Link: http://sl33p3r.free.fr/tutorials/rails/wiki/wiki-en.html

Free rail applications

This website is a great place to look for help with your website, you can find applications created by people who have kindly allowed the public to download and use them. You can find forums, bloggers , message boards etc. Bewarned not all projects have downloadable applications as they are still in progress. Link: https://rubyforge.org/


EBooks

Some good books to get hold of and download are:- Apress Beginning Ruby From Novice to Professional Mar 2007 - this starts at a real dummy level and then gets more in depth as you go along. Rails Recipes - this book is great you can look through the book for an app you want and it tells you step by step how to build it. both of these books can be *purchased* or loaned through the LC .

Some rails 2.0 tutorials: http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial

Troubleshooting

Got a problem? Found a fix? If so, why not post your problems and solutions here for others to benefit from?


Mystery Process Holds Onto WEBrick Port

This plagued me for a few days - basically WEBrick refuses to run because a mystery process is holding onto port 3000.

Run netstat in a command prompt(Start>Run>type "cmd" then return then "netstat" into the prompt followed by return)-this shows all of the ports that are open and what processes own them. If localhost:3000 is shown then close the respective process from the task manager (hit Ctrl+Alt+Del together) and reboot WEBrick. If there is no process on port 3000 then read on...

Firewall - Try adding port 3000 to the firewalls safe-list and reboot WEBrick. If this yields no result disconnect from the internet (for security reasons) and disable all firewalls (including the Windows firewall) and try again. Whether this works or not, don't forget to turn your firewalls back on before reconnecting to the internet.

Windows Live Messenger - Messenger has been known to hog port 3000 so kill it, reboot WEBrick and see if it runs. If it does you should then be able to run Messenger again alongside WEBrick.

PDA's - Do you have a PDA/phone docked and connected via MS ActiveSync? If so then this is probably where your problem lies. Physically remove your PDA/phone from its dock and close ActiveSync. Then open the task manager (Ctrl+Alt+Del) and kill the "wcescomm.exe" process. Reboot WEBrick.

Props goto the RoR Wiki and Andre in LA for these fixes.