Yet Another Rails Newbie

July 7, 2006

We’re moving!

Filed under: Uncategorized — hittingthebuffers @ 10:46 pm

This blog is moving soon. Most of the posts here have already been transferred over and new ones will only appear there.

June 26, 2006

It’s all brackets

Filed under: RubyOnRails — Richard @ 8:25 pm

I’ve been experimenting using the following code to retrieve HTML from various sites:

require 'open-uri'

class DemoController < ApplicationController
def index
open('http://www.google.co.uk/search?q=ruby') {
|html| render_text html.read()
}
end
end

If you try it, you’ll get the HTML for a Google results page. So far so good.
However, this is where I’m stuck. One site I’ve been trying to access passes a GUID in the querystring and it’s wrapped in curly brackets. So I updated the ‘open’ line to say:

open('http://www.google.co.uk/search?q={3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}') {then refreshed my browser; only to be presented with the following error:

URI::InvalidURIError in DemoController#index

bad URI(is not URI?): http://www.google.co.uk/search?q={3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
RAILS_ROOT: /code/public/../config/..
/usr/local/lib/ruby/1.8/uri/common.rb:432:in `split'
/usr/local/lib/ruby/1.8/uri/common.rb:481:in `parse'
/usr/local/lib/ruby/1.8/open-uri.rb:85:in `open'
#{RAILS_ROOT}/app/controllers/demo_controller.rb:5:in `index'

From what I’ve read, curly brackets aren’t allowed in a Ruby URI (despite my browser being capable of using them). I’ve tried encoding them but then the page is called with the encoded version, which in my case, the site isn’t expecting and it doesn’t work.

What I’m looking for is a way to allow an ‘unsafe’ URI to be called. Does anyone know if that’s possible?

June 19, 2006

Ooh, that’s clever.

Filed under: RubyOnRails — hittingthebuffers @ 10:09 pm

While knocking together a new Rails app earlier I typed script/generate model Binding and expected the usual list of created files and directories. Instead I got this:


Po:~/rails/woms eifs$ script/generate model binding
The name 'Binding' is reserved by Ruby on Rails.
Please choose an alternative and run this generator again.

Suggestions:

Sense 1
binding -- (the capacity to attract and hold something)
=> attraction, attractiveness -- (the quality of arousing interest; being attractive or something that attracts; "her personality held a strange attraction for him")

Sense 2
binding -- (strip sewn over or along an edge for reinforcement or decoration)
=> sewing, stitchery -- (needlework that involves sewing; "she put her sewing back in the basket")

Sense 3
dressing, bandaging, binding -- (the act of applying a bandage)
=> medical care, medical aid -- (professional treatment for illness or injury)

Sense 4
binding, book binding, cover, back -- (the front and back covering of a book; "the book had a leather binding")
=> protective covering, protective cover, protection -- (a covering that is intend to protect from damage or injury; "they had no protection from the fallout"; "wax provided protection for the floors")

June 5, 2006

Migrate the way.

Filed under: ActiveRecord, RubyOnRails — Richard @ 10:13 pm

Yesterday I spent a couple of hours fathoming out how to use migration. I've read several articles and blogs saying that this is the best way to create your database tables in Rails, so thought I'd give it a go.

Firstly, the fact that it's possible to update your database schema, or rollback to a previous version seemed great. You simply type ruby script/generate migration SomeDescription and you have a file created in the db/migrate folder called something like 001_some_description.rb.

Then, next time you want to modify the database you type ruby script/generate migration AnotherDescription and another file called 002_another_description.rb would appear. So far so good.

But what happens if there's a problem in your migration code. For example, I accidentally had a field of type :booolean (with the extra 'o'). Then, when I ran rake migrate, there was a MySQL error and the migration stopped. Some of the migration had succeeded and one of the tables had been created, but the schema_info table which tracks which version is actually in the database still contained the previous version number. It seemed odd that if a migration fails, then it doesn't automatically call the self.down method to restore the database to the working version. Instead, I manually had to go into the MySQL command line, type UPDATE schema_info SET version = 2 (which was the version that failed) and then I could use rake migrate VERSION=1 to undo the partly updated tables. I was then able to correct my typo and re-rake the migration. Also noting that VERSION has to be in upper case which caught me out the first time I tried. I guess I could have manually undone the changes that Rails had made, but since I'd already defined these for the rollback, it seemed easier to use rake.

Another thing which I wasn't sure about was foreign keys. I'm a full time web developer and at work, whenever there are relationships, there are foreign keys. I was surprised to find that Rails doesn't have them! I knew about has_many and belongs_to – but these, to my surprise didn't enforce any data integrity. So I could have any value in one table that didn't exist in the id column of another. I wasn't happy about this. There had to be some way to stop this from happening. After many searches on Google, I found that it's possible to add validation to the model before data is inserted into the database:

class Site < ActiveRecord::Base
   belongs_to :category

   def validate
      errors.add_to_base "Error description" unless Category.exists?(category_id)
   end
end

Which did just what I wanted. Every row that was inserted into the sites table, would check that the category Id existed in categories and fail if it wasn't valid.

However, there's an even better way (as I see it at the moment). RedHill Consulting have created a Rails plugin (http://www.redhillconsulting.com.au/rails_plugins.html) which adds a foreign key to the database when you rake. All you have to do it run these two commands after making sure that SVN is installed on your computer (OSX users go here: http://www.codingmonkeys.de/mbo/):

script/plugin install svn://rubyforge.org//var/svn/redhillonrails/trunk/vendor/plugins/schema_defining

script/plugin install svn://rubyforge.org//var/svn/redhillonrails/trunk/vendor/plugins/foreign_key_migrations

Then, each time you migrate, the foreign keys are added to the database. I've only tried this using MySQL for now but from what I think I read, it should work for others too.

Discuss.

June 4, 2006

New Newbie

Filed under: Uncategorized — Richard @ 11:07 pm

Thanks to HittingTheBuffers who has let me post, I'll be adding my Rails findings and hopefully helping out anyone else who's just as stuck as me.

May 5, 2006

At last, a good rails reference

Filed under: RubyOnRails, documentation — hittingthebuffers @ 8:14 am

Rails is great but the documentation is currently less so. There are some good books around, but nothing until now that’s provided a short reference to the stuff a new Rails developer will use the most in that phase between total newbie and reasonably competent. Thankfully, I’ve now found out about the Ruby on Rails Short Reference, a 24 page PDF which seems to provide most of the stuff I haven’t quite memorised the syntax for yet.

April 25, 2006

has_one or belongs_to?

Filed under: ActiveRecord, RubyOnRails, Uncategorized — hittingthebuffers @ 9:38 am

One of the things that took a little more understanding than usual was the correct use of the ActiveRecord methods that define the relationships between your objects. I was often unsure whether to use has_one or belongs_to.

I have to write pub quizzes every so often. I had a quickly scaffolded together rails app to help me write them but it lacked all but the most basic features. So, I started a new one. I realised that I needed three tables: quizzes, questions and categories. I wrote the migrations and tried to set up the relationships in the created models. When I tried to test what I’d written in script/console. I could create quizzes and add questions to them but not assign the questions to a category. This baffled me for a while.

After going off and doing something else for a while I came back to the code and the database diagram and realised my error. While I’d correctly said that a question belonged_to a quiz, I’d not done the same with the categories and had thought that a question had a category. Looking again at the database structure I realised that the relationships work like this: The table with the foreign key in it belongs_to the table that that foreign key references. In my case my questions table had a quiz_id and a category_id. Therefore a Question has a belongs_to relationship with both the Quiz and Category models which both in turn have has_many relationships with Question.

I made the changes and it works now. It’s always good when something clicks into place.

April 23, 2006

What’s this all about then?

Filed under: Uncategorized — hittingthebuffers @ 11:15 am

Like a lot of web developers I heard about Rails last year and began to get interested it. Owning a Mac meant that it was fairly easy to get Rails installed and get up and running. Since then I’ve played with Rails but not written a full application yet. One of the problems I’ve encountered is the rather disparate nature of the documentation. So, the plan for this blog is to keep learning Rails and to document all of the useful links I find.

Blog at WordPress.com.