Difference between revisions of "Workbook"
(46 intermediate revisions by 12 users not shown) | |||
Line 8: | Line 8: | ||
# 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: | # 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: | ||
# gem install rails -y | # gem install rails -y | ||
+ | # (i found that you had to be in the ruby/bin directory for the gem command to work)0503201 | ||
# 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: | # 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: | ||
# set path=%PATH%;j:\ruby\bin; | # set path=%PATH%;j:\ruby\bin; | ||
Line 57: | Line 58: | ||
==MVC & Controllers== | ==MVC & Controllers== | ||
# Using the instructions given above, create a new application called myapp, connected to a sqlite database, and cd into the directory. | # Using the instructions given above, create a new application called myapp, connected to a sqlite database, and cd into the directory. | ||
− | # Create a controller using ruby script/generate controller Say | + | # Create a controller using "ruby script/generate controller Say" --[[User:0623815|0623815]] 22:03, 2 April 2008 (BST) |
# cd into the app\controllers directory and open the say_controller.rb skeleton. | # cd into the app\controllers directory and open the say_controller.rb skeleton. | ||
# Add the hello class as shown below:[[Image:Workbook04.gif|center]] | # Add the hello class as shown below:[[Image:Workbook04.gif|center]] | ||
Line 90: | Line 91: | ||
This creates a model called student (and by convention a db table called students) | 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. | 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 ''' | + | 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! | 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! | ||
# Start the application with ruby script/server, start a browser (firefox?) and navigate to http://localhost:3000/students (based on the example above) | # Start the application with ruby script/server, start a browser (firefox?) and navigate to http://localhost:3000/students (based on the example above) | ||
Line 103: | Line 104: | ||
# Create a controller called info using the ruby script command (see above). Edit the file to be as below:[[Image:Workbook09.gif|center]] | # Create a controller called info using the ruby script command (see above). Edit the file to be as below:[[Image:Workbook09.gif|center]] | ||
# 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. | # 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. | ||
− | # 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[[Image:Workbook10.gif|center]] | + | # Next create a new view with the extension rxml (remember to save it in the right folder in views, in this case the "info" folder) – 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[[Image:Workbook10.gif|center]] |
+ | |||
+ | Note: remember if you are following the previous examples to check your attribute names! In this case s.stud_no would be s.s_no | ||
# This will create an xml file as shown below (depending on the data stored):[[Image:Workbook11.gif|center]] | # This will create an xml file as shown below (depending on the data stored):[[Image:Workbook11.gif|center]] | ||
+ | |||
+ | Edit: Added some clarity to step 3, as well as a caution note - [https://mi-linux.wlv.ac.uk/wiki/index.php/User:0623089 0623089] | ||
== Rails and testing == | == 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. | * 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. | * Type '''rake db:test:prepare''' at the command prompt. | ||
+ | * Note if you encounter any errors type in the command '''gem install rake''' this will reinstall rake to the latest version | ||
* 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. | * 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 | * 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 | ||
Line 138: | Line 144: | ||
* Note that it already has data, and it is valid data too.. | * Note that it already has data, and it is valid data too.. | ||
+ | |||
+ | Edit - Added help for rake command --[[User:0609311|0609311]] 15:15, 4 April 2008 (BST) | ||
==Simple Ajax 'Live Search'== | ==Simple Ajax 'Live Search'== | ||
Line 147: | Line 155: | ||
* Create a model (ruby script/generate model Book) | * Create a model (ruby script/generate model Book) | ||
* Create a controller (ruby script/generate controller books) | * Create a controller (ruby script/generate controller books) | ||
− | * Edit the migrate script found in | + | * Edit the migrate script found in db/migrate to be as shown below |
class CreateBooks < ActiveRecord::Migration | class CreateBooks < ActiveRecord::Migration | ||
Line 173: | Line 181: | ||
(you can change book titles if you like!) | (you can change book titles if you like!) | ||
+ | |||
+ | * Create the table using '''rake db:migrate''' | ||
+ | |||
* Create a layout (html file) in the views/layouts folder called books.rhtml. File contents shown below: | * Create a layout (html file) in the views/layouts folder called books.rhtml. File contents shown below: | ||
Line 256: | Line 267: | ||
That’s all – run your new application and watch the live search – note not a line of javascript in sight – the power of rails! | That’s all – run your new application and watch the live search – note not a line of javascript in sight – the power of rails! | ||
+ | |||
+ | ==BEST RAILS 2.0 TUTORIAL== | ||
+ | |||
+ | Rails 2.0 step by step. | ||
+ | This is a multi-part tutorial. It will cover enough to get a scaffolded Rails application up and running under Rails 2.0. | ||
+ | Link below: | ||
+ | http://fairleads.blogspot.com/2007/12/rails-20-and-scaffolding-step-by-step.html | ||
+ | |||
+ | |||
+ | ==TOP 12 RUBY ON RAILS TUTORIAL== | ||
+ | In the spirit of sharing, here are the 12 tutorials that I found most useful: | ||
+ | 1. ROLLING WITH RUBY ON RAILS: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html | ||
+ | |||
+ | 2. ROLLING WITH RUBY ON RAILS PT2 http://www.onlamp.com/pub/a/onlamp/2005/03/03/rails.html | ||
+ | |||
+ | 3. FOUR DAYS ON RAILS(PDF) http://rails.homelinux.org/ | ||
+ | |||
+ | 4. REALLY GETTING STARTED WITH RAILS: http://www.slash7.com/articles/2005/01/24/really-getting-started-in-rails | ||
+ | |||
+ | 5. TUTORIAL I RUBY ON RAILS: http://wiki.rubyonrails.com/rails/pages/Tutorial | ||
+ | |||
+ | 6. FAST-TRACK YOUR WEB-APPS WITH RUBY ON RAILS: | ||
+ | http://www-128.ibm.com/developerworks/linux/library/l-rubyrails/ | ||
+ | |||
+ | 7. GETTING YOUR FEET WET WITH RUBY ON RAILS: | ||
+ | http://webmonkey.wired.com/webmonkey/05/28/index4a.html | ||
+ | |||
+ | 8. HOW TO MAKE A TODO LIST PROGRAM WITH RAILS: | ||
+ | http://darkhost.mine.nu:8080/~vince/rails/tutorial.html | ||
+ | |||
+ | 9. AJAX ON RAILS: http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html | ||
+ | |||
+ | 10. MANY TO MANY TUTORIALS ON RAILS(PDF): | ||
+ | http://webmonkey.wired.com/webmonkey/05/28/index4a.html | ||
+ | |||
+ | 11. DISTRIBUTING RAILS APPLICATION- A TUTORIAL: | ||
+ | http://www.erikveen.dds.nl/distributingrubyapplications/rails.html | ||
+ | |||
+ | 12. Installing Ruby on Rails with Lighttpd and MySQL on Fedora Core 4 | ||
+ | http://digitalmediaminute.com/howto/fc4rails/ | ||
==Ajax can move == | ==Ajax can move == | ||
Line 278: | Line 329: | ||
If you find this very usefull here is a sort of puzzle game, proberly best if you don't know javascript to stay clear clear but looking never hurts:http://wiki.script.aculo.us/scriptaculous/page/print/SortableFloatsDemo | If you find this very usefull here is a sort of puzzle game, proberly best if you don't know javascript to stay clear clear but looking never hurts:http://wiki.script.aculo.us/scriptaculous/page/print/SortableFloatsDemo | ||
+ | |||
+ | ==Quick 5 minute AJAX Tutorial :D== | ||
+ | This tutorial is simple and can be achieved in 5 minutes, it just brings up the current time when you click a link and the best thing about it is that the page doesn't have to be refreshed. | ||
+ | |||
+ | First of all create a demo controller | ||
+ | |||
+ | in your command prompt or putty enter: | ||
+ | ruby script/generate controller demo | ||
+ | |||
+ | |||
+ | *then go into your demo controller and edit it so it looks like this: | ||
+ | |||
+ | [[Image:demo.controller.GIF]] | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | *Then we need to create a view, open up a text editor, save it as index.html.erb and save it in views/demo/ and put the following code in: | ||
+ | |||
+ | |||
+ | [[Image:demo.index.GIF]] | ||
+ | |||
+ | |||
+ | *Make sure the endend is underneath and on two seperate lines like | ||
+ | end | ||
+ | end | ||
+ | |||
+ | |||
+ | *now run your server and it should work, if your working through localhost:3000/demo. | ||
+ | |||
+ | any problems email i.02@wlv.ac.uk :D | ||
==Simple rss feed == | ==Simple rss feed == | ||
Line 296: | Line 378: | ||
Very easy and very clean, try this if your having trouble with the xml tutorial and for the fact I worked hard to get it working. | Very easy and very clean, try this if your having trouble with the xml tutorial and for the fact I worked hard to get it working. | ||
+ | |||
+ | |||
+ | == Another simplier RSS feed thats java script! (for anyone who has an extension!) == | ||
+ | I went onto the internet to find if there where any easier ways of setting up a RSS feed there actual is! I went to this link; | ||
+ | http://rssfeedreader.com/ | ||
+ | Go onto the link and sign up you can choose from lots of different subjects that may be relevent to you site! | ||
+ | Heres some sample code from my site just to show how easy it is; | ||
+ | <script language=javascript | ||
+ | src="http://rssfeedreader.com/rss3/rss.php?url=http%3A%2F%2Fwww.nytimes.com%2Fservices%2Fxml%2Frss%2Fnyt%2FBooks.xml&newpage=1&chead=1&atl=1&desc=1&owncss=&eleminate=&auth=1&dts=1&width=300&max=5&tlen=0&rnd=1&bt=3&bs=Double&nmb=&ntb=&naf=&nst=&nwd=0&nht=0&dlen=0&lstyle=-1&lc=Blue&bg=White&bc=Gray&spc=&ims=&tc=&ts=11&tfont=Verdana,+Arial,+Sans-serif"></script> | ||
== XML == | == XML == | ||
Line 353: | Line 444: | ||
==Tips & tricks == | ==Tips & tricks == | ||
''Please add to this as you find interesting or useful things'' | ''Please add to this as you find interesting or useful things'' | ||
+ | |||
+ | '''Add Login System using Restul authentication''' | ||
+ | |||
+ | Adding login system to your application is very easy and straight forward process. | ||
+ | |||
+ | Run the following commands in command prompt: | ||
+ | |||
+ | script/plugin source http://svn.techno-weenie.net/projects/plugins | ||
+ | |||
+ | script/plugin install restful_authentication | ||
+ | |||
+ | script/generate authenticated user sessions | ||
+ | |||
+ | |||
+ | |||
+ | Then edit the following to controller application.rb. It should look like | ||
+ | |||
+ | require 'authenticated_system' | ||
+ | |||
+ | class ApplicationController < ActionController::Base | ||
+ | |||
+ | include AuthenticatedSystem | ||
+ | |||
+ | helper :all # include all helpers, all the time | ||
+ | |||
+ | # See ActionController::RequestForgeryProtection for details | ||
+ | # Uncomment the :secret if you're not using the cookie session store | ||
+ | protect_from_forgery # :secret => 'e6cbde049f68cf82c182547852970cd8' | ||
+ | end | ||
+ | |||
+ | |||
+ | |||
+ | Then edit the following to all the controllers you require login. should look like | ||
+ | |||
+ | class ArticlesController < ApplicationController | ||
+ | |||
+ | before_filter :login_required | ||
+ | |||
+ | |||
+ | |||
+ | If you require login for any particular method eg add and edit then you can add it | ||
+ | |||
+ | before_filter :login_required, :only => [:edit, :update, :new, :destroy] | ||
+ | |||
+ | |||
+ | |||
+ | Thats all done now you can check your app | ||
+ | |||
+ | The user can signup at http://localhost:3000/users/new | ||
+ | |||
+ | it will take the user to index page which is http://localhost:3000 | ||
'''Using the Amazon API''' | '''Using the Amazon API''' | ||
Line 468: | Line 610: | ||
Link: http://www.rubyplus.org/episodes/19-AWDR-Depot-App-using-Rails-2-version.html | Link: http://www.rubyplus.org/episodes/19-AWDR-Depot-App-using-Rails-2-version.html | ||
+ | |||
+ | ==Expanding/Collapsing divs== | ||
+ | Here's a simple AJAX function to display and hide a div | ||
+ | <%= link_to_function "Text in link", "Element.toggle('divID')" %> | ||
+ | |||
+ | Then simply create a div with the same id as in the toggle statement | ||
+ | If you want the div to be inivisible when the page loads, add style="display: none; | ||
+ | If you want to div to be visible to start with, simply remove the style="display: none;" | ||
+ | |||
+ | |||
+ | |||
==Comments== | ==Comments== | ||
Line 497: | Line 650: | ||
Thats it! Your generated documentation now lies at YOURAPP/doc/index.html. | Thats it! Your generated documentation now lies at YOURAPP/doc/index.html. | ||
+ | |||
+ | ==Uploading images (or other files)== | ||
+ | |||
+ | Uploading photos with Rails | ||
+ | To upload photos to rails, add the following fields to your migration | ||
+ | |||
+ | t.string :name | ||
+ | t.string :content_type | ||
+ | t.binary :data | ||
+ | |||
+ | “name” will be the name of your uploaded file<br /> | ||
+ | “content_type” will be the type of file uploaded<br /> | ||
+ | “data” will be the raw binary data of your file | ||
+ | |||
+ | Add the following to your view | ||
+ | |||
+ | In the form_for section at the top of the form | ||
+ | { :multipart => true }) | ||
+ | |||
+ | And in the body of the form | ||
+ | <%= f.file_field :uploaded_picture %> | ||
+ | |||
+ | As you can see, we have no field in our migration called uploaded_picture. This is dealt with in the model. | ||
+ | |||
+ | This method takes uploaded file and stores it in the database as binary data unless the user has left the field blank. | ||
+ | |||
+ | def uploaded_picture=(picture_field) | ||
+ | unless picture_field.blank? | ||
+ | self.name = base_part_of(picture_field.original_filename) | ||
+ | self.content_type = picture_field.content_type.chomp | ||
+ | self.data = picture_field.read | ||
+ | end | ||
+ | end | ||
+ | |||
+ | def base_part_of(file_name) | ||
+ | File.basename(file_name).gsub(/[^\w._-]/, '' ) | ||
+ | end | ||
+ | |||
+ | Finally, add the following to your validations in your model | ||
+ | |||
+ | |||
+ | validates_format_of :content_type, | ||
+ | :with => /^image/, | ||
+ | :message => "-- you can only upload pictures", | ||
+ | :allow_nil => true | ||
+ | |||
+ | This ensures that users can only upload images to your database. | ||
+ | The allow_nil part means that you can make the uploading of files an optional feature rather than a requirement. | ||
+ | |||
+ | That's all you need for storing the image. Now for displaying it. | ||
+ | |||
+ | Go to your controller and add the following: | ||
+ | |||
+ | def picurl | ||
+ | @user = User.find(params[:id]) | ||
+ | send_data(@user.data, | ||
+ | :filename => @user.name, | ||
+ | :type => @user.content_type, | ||
+ | :disposition => "inline" ) | ||
+ | end | ||
+ | |||
+ | This generates a url for your image when given the id. | ||
+ | |||
+ | Finally, in the view which you want your image to display: | ||
+ | |||
+ | |||
+ | <% unless @user.data.nil? %> | ||
+ | <img src="<%= url_for(:action => 'picurl', :id => @user.id) %>" /> | ||
+ | <% end %> | ||
+ | |||
+ | The unless statement is important as otherwise the view will try to display the image even if it is not there. | ||
+ | |||
+ | That's all! | ||
+ | |||
+ | Adding images in HTML... I noticed the images wouldn't appear by typing the following: | ||
+ | <IMG SRC="bar2.gif" alt="bar"> | ||
+ | |||
+ | The way you would normally type it for HTML. All the images must first be saved in the Public, Images folder and then the whole path must be typed. This will then make the image appear. | ||
+ | |||
+ | <IMG SRC="E:\railsapps\mytest\public\images\bar2.gif" alt="bar"> | ||
+ | |||
+ | ==Passing hidden values in a form== | ||
+ | |||
+ | If you need to pass a value that does not change from a form to a controller, but you don't want the user to see or have access to it, you can use the following method. | ||
+ | |||
+ | This example uses the current user's ID as the value, but you can use anything you want | ||
+ | <%= f.hidden_field :user_id, :value => session[:user][:id] %> | ||
+ | |||
+ | Easy! | ||
+ | |||
+ | ==Populating drop-down boxes with records from a table== | ||
+ | |||
+ | If you want a drop-down box which only contains values of records in a table, you can use this method. | ||
+ | |||
+ | In your controller, do a basic search for whatever records you want to use IE | ||
+ | |||
+ | @things = Thing.find(:all) | ||
+ | |||
+ | Then in your view, use collection select like this: | ||
+ | <%= collection_select("A", "B" , "C", "D", "E") %> | ||
+ | |||
+ | Where:<br /> | ||
+ | A = The model you are trying to create with the form<br /> | ||
+ | B = The name of the field in your new record which will reference the other model, eg "thing_id"<br /> | ||
+ | C = The collection you found in the controller, eg "@things"<br /> | ||
+ | D = ID field of the record looked up in @things, should just be "id"<br /> | ||
+ | E = The field from the lookup model that you want to be displayed in the drop down box<br /> | ||
+ | |||
+ | Finally, if you want a blank field in your drop down box, add the following code to the statement: | ||
+ | |||
+ | { :include_blank => true } | ||
+ | |||
+ | ==Routes== | ||
+ | |||
+ | You may have had a few problems with the restful routes system in Rails if, for example, you created a scaffold, then tried to add another action/view to your controller. You probably got a message saying something along the lines of "Could not find a user with ID="pagename"" | ||
+ | |||
+ | This is related to the following statement in the routes file. | ||
+ | |||
+ | map.connect ':controller/:action/:id' | ||
+ | |||
+ | If you type "rake routes" into your command prompt, you will get a list of all the routes your application uses. You should see something like this: | ||
+ | |||
+ | user GET /users/:id {:controller=>"users", :action=>"show"} | ||
+ | |||
+ | This is matched by the URL "/users/pagename", which is causing you to be sent to the show action, which in turn looks for a record called "pagename". | ||
+ | |||
+ | Restful URLS are produced by the following line in the routes file: | ||
+ | map.resources :users | ||
+ | |||
+ | To get your new page to work, there are two options you can take.<br /> | ||
+ | 1: Comment out the line completely, which will get rid of restful URLS<br /> | ||
+ | 2: Update the resources line to specify your new action. As follows | ||
+ | |||
+ | map.resources :users, :member => { :my_action => :get } | ||
+ | |||
+ | means that your application will now accept URLs of the form | ||
+ | /users/:id/my_action (the "rake routes" command will show this change to | ||
+ | the routes). Alternatively, if the action doesn't require a specific | ||
+ | ID, then use the :collection argument: | ||
+ | |||
+ | map.resources :users, :collection => { :my_action => :get } | ||
+ | |||
+ | This means you can access the URL /users/my_action and reach your | ||
+ | action. You can change :get to :post if the action must only apply to | ||
+ | POST requests. Other possibilities are :put, :delete and :any. You can | ||
+ | add both :member and :collection actions if you need to. | ||
+ | |||
+ | Have a look at #resources in the documentation: | ||
+ | |||
+ | http://api.rubyonrails.com/classes/ActionController/Resources.html#M000308 | ||
+ | |||
+ | ==Using the database to store sessions== | ||
+ | |||
+ | If you are using a large amount of data in your sessions, you may find that your application is running very slowly or if you are using file uploads, you may find it dies altogether. I found that after using the database to store my sessions, it became a lot more reliable. | ||
+ | |||
+ | Go to your environment.rb file and look for the section that says | ||
+ | |||
+ | # Use the database for sessions instead of the cookie-based default, | ||
+ | # which shouldn't be used to store highly confidential information | ||
+ | # (create the session table with 'rake db:sessions:create') | ||
+ | # config.action_controller.session_store = :active_record_store | ||
+ | |||
+ | Uncomment the last line, then in application_controller.rb, look for this section. | ||
+ | |||
+ | # See ActionController::RequestForgeryProtection for details | ||
+ | # Uncomment the :secret if you're not using the cookie session store | ||
+ | #protect_from_forgery :secret => '5c0cf093b4866f589b91a08c048f7bfa' | ||
+ | |||
+ | Again, uncomment the last line | ||
+ | |||
+ | Don't forget to create your sessions table in the database! | ||
+ | |||
+ | rake db:sessions:create | ||
+ | rake db:migrate | ||
+ | |||
+ | It should all be working now! | ||
+ | |||
+ | ==CoUNTING user Profil view== | ||
+ | == counting User Profile views == | ||
+ | |||
+ | set up a table for the view count as follows: | ||
+ | |||
+ | 1 | ||
+ | |||
+ | |||
+ | |||
+ | create_table :user_views do |t| t.column :user_profile_id, :integer t.column :count, :integer, :default => 1 t.column :created_at, :datetime end | ||
+ | |||
+ | 2- create controller called User, | ||
+ | |||
+ | |||
+ | |||
+ | Class UserController < ApplicationController | ||
+ | def view | ||
+ | unless @user == current_user | ||
+ | session[:visited_profiles] << user_profile.id unless session[:visited_profiles].include?(user_profile.id) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | 3-add session | ||
+ | class Session < ActiveRecord::Base before_destroy :update_page_views def update_page_views visited = CGI::Session::ActiveRecordStore::Session.unmarshal(Session.find(:first).data)[:visited_profiles] return if visited.blank? visited.each do |p| UserView.increment_or_create(:user_profile_id => p) end end | ||
+ | |||
+ | |||
+ | 4- go in to model => user view => increment_or_create and add this code. | ||
+ | def self.increment_or_create(attributes={}) | ||
+ | if (view = self.find_by_user_profile_id(attributes[:user_profile_id])) | ||
+ | view.update_attributes(:count => (view.count +=1)) | ||
+ | else | ||
+ | self.create(attributes) | ||
+ | end | ||
+ | end | ||
+ | |||
==Troubleshooting== | ==Troubleshooting== |
Latest revision as of 15:23, 11 April 2008
XML and Web Services >> Workbook
Ruby install on a USB stick
- 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?)
- Double-click on the installer, after clicking next a few times, a screen like the one shown below is displayed.
- Ensure you install on your USB stick, not the C drive (check the drive letter, as shown. Mine is J:, yours may vary)
- 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:
- gem install rails -y
- (i found that you had to be in the ruby/bin directory for the gem command to work)0503201
- 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:
- set path=%PATH%;j:\ruby\bin;
- 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.
- 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:
- Create a program that can take a phrase as input and print it out in reverse.
- Create a program that can take a phrase as input and output it’s length as a number
- Create an application that can encrypt any phrase you enter using the rot13 algorithm
- Create an application that can take a temperature in F or C and convert to the other form
SQLite install on Windows
- 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:
- 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.
- Next use the gem command again to install the ruby-sqlite bindings so that ruby can use sqlite. The command is given below:
- gem install sqlite3-ruby (choose option 1 from the menu)
- Rails apps should be stored in their own directory – I tend to call it railsapps. Create this directory on your usb stick
- To test that rails is working properly type the following commands:
- cd railsapps
- rails mytest --database=sqlite3
- cd mytest
- ruby script/server
- 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.
- 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
- Using the instructions given above, create a new application called myapp, connected to a sqlite database, and cd into the directory.
- Create a controller using "ruby script/generate controller Say" --0623815 22:03, 2 April 2008 (BST)
- cd into the app\controllers directory and open the say_controller.rb skeleton.
- Add the hello class as shown below:
- Create a new view template in the app\views\say directory, called hello.rhtml
- Code is given below:
- Test the above, what do you see? (http://localhost:3000/say/hello - don't forget to start server again 'ruby script/server')
- Add a goodbye method to the say controller using the instructions above.
- Create a goodbye view to accompany the goodbye method, but change the message to “see you later”
- Modify the hello view to have a link to the goodbye view, example below:
- 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)
- Create a link from goodbye back to hello
- 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!
- Start the application with ruby script/server, start a browser (firefox?) and navigate to http://localhost:3000/students (based on the example above)
- Add some data by clicking on ‘new student’ and filling in the boxes that are displayed – remember to click ‘create’ after each entry.
- What happens if you leave any field blank? Is this what you require?
- 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:
(EDIT) - IMAGE ATTACHED TO REFLECT WHAT IS WRITTEN IN INSTRUCTIONS
- Create a new entry, but leave the stud_no and course fields blank. What happens? Is this a useful function?
- Experiment with the validation helpers to see if you can ensure that the student number lies within a certain range.
Views & templates
- Create a controller called info using the ruby script command (see above). Edit the file to be as below:
- 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.
- Next create a new view with the extension rxml (remember to save it in the right folder in views, in this case the "info" folder) – 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
Note: remember if you are following the previous examples to check your attribute names! In this case s.stud_no would be s.s_no
- This will create an xml file as shown below (depending on the data stored):
Edit: Added some clarity to step 3, as well as a caution note - 0623089
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 if you encounter any errors type in the command gem install rake this will reinstall rake to the latest version
- 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
- 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
- If you run the test program what happens? You should get an output as below. Is this what you expected? Why?
- 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:
- Note that it already has data, and it is valid data too..
Edit - Added help for rake command --0609311 15:15, 4 April 2008 (BST)
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 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 the table using rake db:migrate
- 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. The image below shows how I used a table for my own website, hope this helps.
That’s all – run your new application and watch the live search – note not a line of javascript in sight – the power of rails!
BEST RAILS 2.0 TUTORIAL
Rails 2.0 step by step. This is a multi-part tutorial. It will cover enough to get a scaffolded Rails application up and running under Rails 2.0. Link below: http://fairleads.blogspot.com/2007/12/rails-20-and-scaffolding-step-by-step.html
TOP 12 RUBY ON RAILS TUTORIAL
In the spirit of sharing, here are the 12 tutorials that I found most useful:
1. ROLLING WITH RUBY ON RAILS: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html
2. ROLLING WITH RUBY ON RAILS PT2 http://www.onlamp.com/pub/a/onlamp/2005/03/03/rails.html
3. FOUR DAYS ON RAILS(PDF) http://rails.homelinux.org/
4. REALLY GETTING STARTED WITH RAILS: http://www.slash7.com/articles/2005/01/24/really-getting-started-in-rails
5. TUTORIAL I RUBY ON RAILS: http://wiki.rubyonrails.com/rails/pages/Tutorial
6. FAST-TRACK YOUR WEB-APPS WITH RUBY ON RAILS:
http://www-128.ibm.com/developerworks/linux/library/l-rubyrails/
7. GETTING YOUR FEET WET WITH RUBY ON RAILS: http://webmonkey.wired.com/webmonkey/05/28/index4a.html
8. HOW TO MAKE A TODO LIST PROGRAM WITH RAILS: http://darkhost.mine.nu:8080/~vince/rails/tutorial.html
9. AJAX ON RAILS: http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html
10. MANY TO MANY TUTORIALS ON RAILS(PDF): http://webmonkey.wired.com/webmonkey/05/28/index4a.html
11. DISTRIBUTING RAILS APPLICATION- A TUTORIAL: http://www.erikveen.dds.nl/distributingrubyapplications/rails.html
12. Installing Ruby on Rails with Lighttpd and MySQL on Fedora Core 4 http://digitalmediaminute.com/howto/fc4rails/
Ajax can move
Yes ajax can move, images that is and so simply at that. Give your image an id like the one below and position it on the page where ever you like.
<img id="something" src="something.jpg" alt="whatever" title="whatever"/>
- alt is needed for valid xhtml and title should be used but I think you can leave it out*
Next we want it to move so add this line of code to the page:
<%= draggable_element("something") -%>
Load the page in the browser and ta da when you click on it you can drag it around but of course you will notice it stays where you leave it. So to get it back to its starting location add this line as well.
<%= draggable_element("something", :revert => true) -%>
There you go the image will return to its starting location, just two lines of code to do all that maybe ruby on rails isn't so bad?
If you do find trouble with this then refer to this site: http://www.railshosting.org/#live_searching it has many wonderfull ajax tips on there including the amazing search with a few changes.
If you find this very usefull here is a sort of puzzle game, proberly best if you don't know javascript to stay clear clear but looking never hurts:http://wiki.script.aculo.us/scriptaculous/page/print/SortableFloatsDemo
Quick 5 minute AJAX Tutorial :D
This tutorial is simple and can be achieved in 5 minutes, it just brings up the current time when you click a link and the best thing about it is that the page doesn't have to be refreshed.
First of all create a demo controller
in your command prompt or putty enter:
ruby script/generate controller demo
- then go into your demo controller and edit it so it looks like this:
- Then we need to create a view, open up a text editor, save it as index.html.erb and save it in views/demo/ and put the following code in:
- Make sure the endend is underneath and on two seperate lines like
end end
- now run your server and it should work, if your working through localhost:3000/demo.
any problems email i.02@wlv.ac.uk :D
Simple rss feed
So you have that great site but want an rss feed to allow other sites to show what on yours no problem. Lets start off with the controller
Remember def rss is the method name not the controllor name unless you make it that.
Thats the controller sorted Whatevertable is obviously your table and you can order it by what ever you want eg. id, date created, date updated and so on. Now for the view:
Thats about it, the xml.item is needed to seperate things, the title is needed to identify the something and description is for the description of the something.
It is important to note the two xml.link used; the first one is the link to the related page where the items are in this example, you could put any link for any page here. The second use of xml.link takes you to the location of the item, in this case it would go to the page where the item details are shown. Now just do localhost:3000/yourcontrollername/view name and you should be all done.
Very easy and very clean, try this if your having trouble with the xml tutorial and for the fact I worked hard to get it working.
Another simplier RSS feed thats java script! (for anyone who has an extension!)
I went onto the internet to find if there where any easier ways of setting up a RSS feed there actual is! I went to this link; http://rssfeedreader.com/ Go onto the link and sign up you can choose from lots of different subjects that may be relevent to you site! Heres some sample code from my site just to show how easy it is; <script language=javascript
src="http://rssfeedreader.com/rss3/rss.php?url=http%3A%2F%2Fwww.nytimes.com%2Fservices%2Fxml%2Frss%2Fnyt%2FBooks.xml&newpage=1&chead=1&atl=1&desc=1&owncss=&eleminate=&auth=1&dts=1&width=300&max=5&tlen=0&rnd=1&bt=3&bs=Double&nmb=&ntb=&naf=&nst=&nwd=0&nht=0&dlen=0&lstyle=-1&lc=Blue&bg=White&bc=Gray&spc=&ims=&tc=&ts=11&tfont=Verdana,+Arial,+Sans-serif"></script>
XML
Please look at the following tutorial : https://www6.software.ibm.com/developerworks/education/x-rubyonrailsxml/x-rubyonrailsxml-a4.pdf
Migrations in Rails 2.0x - A Brief overview
Migrations are a very useful tool, especially for those users who change their minds frequently (I hold my hands up to that!). As mentioned in lecture, they are used to manipulate the database schema in a consistent manner, allowing the database to be rolled back, or re-created.
- To create a migration use the following code where migrationname is the name of what you are trying to accomplish.
ruby script/generate migration migrationname
You can also edit the existing migration files (located in db/migrate) to edit the database, before running rake db:reset to reset the entire database. WARNING don't do this if you want to keep data!
An example of a migration file is as follows
class CreateBeer < ActiveRecord::Migration
def self.up
create_table :beer do |t|
t.references :products
t.string :beername
t.text :description
t.string :manufacturer
t.timestamps
end
end
def self.down
drop_table :beer
end
end
Using rails 2, the migrations use "sexy migrations" as above, a shorthand form of creating the migration structure.
- "t" is the object created in the do |t| statement
- t.references is relating to a link to another table (in this case a one to many link to the products table)
- t.string is the string data type, used for short string data.
- t.text specifies that it is a text field (storing more data than a string.
Once you have edited the database migration, you can do several things wih it from the command line. Bear in mind that migrations have numbers at the start of the files, these are the migration version numbers and are used to control database migrations.
- rake db:migrate - will migrate the subsequent versions up from the current version to the database. So if you are on scheme version 4 - it will run migrations 5 and 6.
- rake db:reset - will reset the ENTIRE DATABASE, dropping all tables then re-creating them.
- rake db:rollback - will go one version back within the version numbers.
- rake db:migrate version=3 - will go to version 3 in the migrations
These commands are incredibly useful, as they allow you to edit the schema of the database, without having to worry about doing everything from scratch (and with messy sql queries!)
PS. I have found a resource that may be of use http://dizzy.co.uk/ruby_on_rails/cheatsheets/rails-migrations - bear in mind that these do NOT use the sexy migrations used in rails 2.0.
--0610698 19:38, 27 March 2008 (UTC)
Tips & tricks
Please add to this as you find interesting or useful things
Add Login System using Restul authentication
Adding login system to your application is very easy and straight forward process.
Run the following commands in command prompt:
script/plugin source http://svn.techno-weenie.net/projects/plugins
script/plugin install restful_authentication
script/generate authenticated user sessions
Then edit the following to controller application.rb. It should look like
require 'authenticated_system'
class ApplicationController < ActionController::Base
include AuthenticatedSystem
helper :all # include all helpers, all the time
# See ActionController::RequestForgeryProtection for details # Uncomment the :secret if you're not using the cookie session store protect_from_forgery # :secret => 'e6cbde049f68cf82c182547852970cd8'
end
Then edit the following to all the controllers you require login. should look like
class ArticlesController < ApplicationController
before_filter :login_required
If you require login for any particular method eg add and edit then you can add it
before_filter :login_required, :only => [:edit, :update, :new, :destroy]
Thats all done now you can check your app
The user can signup at http://localhost:3000/users/new
it will take the user to index page which is http://localhost:3000
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)
Rails useful screencasts
These screen casts are playe in quicktime but two of them will be usefull link: http://www.rubyonrails.org/screencasts
Creating a weblog in 15 minutes - will be usefull for those wanting a blog
Putting Flickr on Rails - Flickr is a image upload site but this tutorial will show and tell you how to add it to your website p.s. you will need to get an api key from Flickr, no biggy as I've done this and know it works.
A little tip: open these in a quicktime player or other player so you can pause and go back makes life much easier.
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
Screencasts
If anyone has got the The Pragmatic Programmers 'Agile Web development with Rails' book (modeule guide: essential list), You might notice that the book uses an older version of rails. I have found a website where you can sign up and download screencasts of the same application from the book being developed with the updated version of rails.
Link: http://www.rubyplus.org/episodes/19-AWDR-Depot-App-using-Rails-2-version.html
Expanding/Collapsing divs
Here's a simple AJAX function to display and hide a div
<%= link_to_function "Text in link", "Element.toggle('divID')" %>
Then simply create a div with the same id as in the toggle statement If you want the div to be inivisible when the page loads, add style="display: none; If you want to div to be visible to start with, simply remove the style="display: none;"
Comments
It took me a while to find out how to place multiline comments in my views that contain both html and ruby code. Here's how to do it.
<%
=begin %>
Comment goes here
<%
=end %>
Rails Documentation
RDoc can automatically produce documentation for your source files. To take advantage of this, goto http://www.humyo.com/F/51149-130709771 and unzip the files to a folder of your choice (doesnt need to be in your Ruby installation or RailsApp directory, can be anywhere you want).
Use a command prompt to leap to the directory where the extracted files sit and enter:
ruby install.rb
Once RDoc has installed, jump to your app's root directory (the one with app, public, etc...) and at the command line enter the following:
rdoc
Thats it! Your generated documentation now lies at YOURAPP/doc/index.html.
Uploading images (or other files)
Uploading photos with Rails To upload photos to rails, add the following fields to your migration
t.string :name t.string :content_type t.binary :data
“name” will be the name of your uploaded file
“content_type” will be the type of file uploaded
“data” will be the raw binary data of your file
Add the following to your view
In the form_for section at the top of the form
{ :multipart => true })
And in the body of the form
<%= f.file_field :uploaded_picture %>
As you can see, we have no field in our migration called uploaded_picture. This is dealt with in the model.
This method takes uploaded file and stores it in the database as binary data unless the user has left the field blank.
def uploaded_picture=(picture_field) unless picture_field.blank? self.name = base_part_of(picture_field.original_filename) self.content_type = picture_field.content_type.chomp self.data = picture_field.read end end
def base_part_of(file_name) File.basename(file_name).gsub(/[^\w._-]/, ) end
Finally, add the following to your validations in your model
validates_format_of :content_type, :with => /^image/, :message => "-- you can only upload pictures", :allow_nil => true
This ensures that users can only upload images to your database. The allow_nil part means that you can make the uploading of files an optional feature rather than a requirement.
That's all you need for storing the image. Now for displaying it.
Go to your controller and add the following:
def picurl @user = User.find(params[:id]) send_data(@user.data, :filename => @user.name, :type => @user.content_type, :disposition => "inline" ) end
This generates a url for your image when given the id.
Finally, in the view which you want your image to display:
<% unless @user.data.nil? %> <img src="<%= url_for(:action => 'picurl', :id => @user.id) %>" /> <% end %>
The unless statement is important as otherwise the view will try to display the image even if it is not there.
That's all!
Adding images in HTML... I noticed the images wouldn't appear by typing the following: <IMG SRC="bar2.gif" alt="bar">
The way you would normally type it for HTML. All the images must first be saved in the Public, Images folder and then the whole path must be typed. This will then make the image appear.
<IMG SRC="E:\railsapps\mytest\public\images\bar2.gif" alt="bar">
If you need to pass a value that does not change from a form to a controller, but you don't want the user to see or have access to it, you can use the following method.
This example uses the current user's ID as the value, but you can use anything you want
<%= f.hidden_field :user_id, :value => session[:user][:id] %>
Easy!
Populating drop-down boxes with records from a table
If you want a drop-down box which only contains values of records in a table, you can use this method.
In your controller, do a basic search for whatever records you want to use IE
@things = Thing.find(:all)
Then in your view, use collection select like this:
<%= collection_select("A", "B" , "C", "D", "E") %>
Where:
A = The model you are trying to create with the form
B = The name of the field in your new record which will reference the other model, eg "thing_id"
C = The collection you found in the controller, eg "@things"
D = ID field of the record looked up in @things, should just be "id"
E = The field from the lookup model that you want to be displayed in the drop down box
Finally, if you want a blank field in your drop down box, add the following code to the statement:
{ :include_blank => true }
Routes
You may have had a few problems with the restful routes system in Rails if, for example, you created a scaffold, then tried to add another action/view to your controller. You probably got a message saying something along the lines of "Could not find a user with ID="pagename""
This is related to the following statement in the routes file.
map.connect ':controller/:action/:id'
If you type "rake routes" into your command prompt, you will get a list of all the routes your application uses. You should see something like this:
user GET /users/:id {:controller=>"users", :action=>"show"}
This is matched by the URL "/users/pagename", which is causing you to be sent to the show action, which in turn looks for a record called "pagename".
Restful URLS are produced by the following line in the routes file:
map.resources :users
To get your new page to work, there are two options you can take.
1: Comment out the line completely, which will get rid of restful URLS
2: Update the resources line to specify your new action. As follows
map.resources :users, :member => { :my_action => :get }
means that your application will now accept URLs of the form /users/:id/my_action (the "rake routes" command will show this change to the routes). Alternatively, if the action doesn't require a specific ID, then use the :collection argument:
map.resources :users, :collection => { :my_action => :get }
This means you can access the URL /users/my_action and reach your action. You can change :get to :post if the action must only apply to POST requests. Other possibilities are :put, :delete and :any. You can add both :member and :collection actions if you need to.
Have a look at #resources in the documentation:
http://api.rubyonrails.com/classes/ActionController/Resources.html#M000308
Using the database to store sessions
If you are using a large amount of data in your sessions, you may find that your application is running very slowly or if you are using file uploads, you may find it dies altogether. I found that after using the database to store my sessions, it became a lot more reliable.
Go to your environment.rb file and look for the section that says
# Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information # (create the session table with 'rake db:sessions:create') # config.action_controller.session_store = :active_record_store
Uncomment the last line, then in application_controller.rb, look for this section.
# See ActionController::RequestForgeryProtection for details # Uncomment the :secret if you're not using the cookie session store #protect_from_forgery :secret => '5c0cf093b4866f589b91a08c048f7bfa'
Again, uncomment the last line
Don't forget to create your sessions table in the database!
rake db:sessions:create rake db:migrate
It should all be working now!
CoUNTING user Profil view
counting User Profile views
set up a table for the view count as follows:
1
create_table :user_views do |t| t.column :user_profile_id, :integer t.column :count, :integer, :default => 1 t.column :created_at, :datetime end
2- create controller called User,
Class UserController < ApplicationController
def view unless @user == current_user session[:visited_profiles] << user_profile.id unless session[:visited_profiles].include?(user_profile.id) end end
end
3-add session class Session < ActiveRecord::Base before_destroy :update_page_views def update_page_views visited = CGI::Session::ActiveRecordStore::Session.unmarshal(Session.find(:first).data)[:visited_profiles] return if visited.blank? visited.each do |p| UserView.increment_or_create(:user_profile_id => p) end end
4- go in to model => user view => increment_or_create and add this code.
def self.increment_or_create(attributes={})
if (view = self.find_by_user_profile_id(attributes[:user_profile_id])) view.update_attributes(:count => (view.count +=1)) else self.create(attributes) end end
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.