6
Rails 0.13 Released!
If you haven’t heard already, Rails 0.13 has been released. Contained within the release are over 225 fixes and new features covering areas such as: Ajax, migrations, routes, rendering, and much more.
For a more detailed list, check out the release notes on the Ruby on Rails weblog.
In an earlier blog post, I listed an example of using the find_by_sql function to return a collection of Artist objects. I have since changed my search method to use the find_all function, instead.
artist.rb (old code)
def self.find_by_first_letter(letter = "A")
   find_by_sql ["select a.* from artists a where ucase(left(artist_name, 1)) = ?", letter]
end
artist.rb (new code)
def self.find_by_first_letter(letter = "A")
   find_all ["ucase(left(artist_name, 1)) = ?", letter]
end
I think using the find_all function instead of the find_by_sql function follows the “Ruby on Rails way” more closely. Plus, it’s shorter and, perhaps, easier to understand for people who aren’t familiar with SQL.
Note: Read this post to learn how to implement the same method using the find_all function. - Rory, July 3, 2005
In the lyrics website I’m developing, I’d like to be able to use URLs like this in my administrative back-end:
http://www.website.com/admin/artists/list/A
where, when I visit this URL, a list of artists who’s name begins with the letter A is displayed. This requires the use of the Ruby on Rails find_by_sql method, as there is no way of querying for artists in this manner using the built-in Active Record.
The first thing I did was add a new method to my Artist model that will allow me to search for artists by the first letter of their name.
artist.rb
class Artist < ActiveRecord::Base
has_many :songs, :order => "song_title", :dependent => true
has_many :albums, :order => "album_name", :dependent => true
def self.find_by_first_letter(letter = "A")
find_by_sql ["select * from artists where ucase(left(artist_name, 1)) = ?", letter]
end
end
As you can see, the method find_by_first_letter takes in an argument called “letter” and uses this argument in the function call to find_by_sql. You’ll notice that a question mark appears in the SQL statement where we would actually like the value associated with “letter” to go. Queries created this way are called Parameterized SQL Queries, and by using them, we avoid the possibility of having someone tamper with our query using SQL injection.
Then, in our action, all we have to do is call our new method.
admin_controller.rb
@artists = Artist.find_by_first_letter(@params["letter"])
I found the old HTML version of Programming Ruby: The Pragmatic Programmer’s Guide the other day, while searching Google for solutions to a Ruby syntax problem I was dealing with. It’s now bookmarked for later reference, just as the other links included in this post are. (The newer version is also available.)
A little Googling later, I came across RailsFAQ.org, which lists solutions to a number of common problems that Ruby on Rails newcomers face.
One of the links was to Hieraki, which is a web application developed using Ruby on Rails. The website is powered by Trac, which is an “enhanced wiki and issue tracking system for software development projects.” It allows you to navigate Hieraki and view the source code for its files. So, I’ve found myself glancing at the Hieraki source code every so often to see how its authors implemented features that I’d like to implement mine, just to see if I’m on the right track.
Note: I have been meaning to re-write this post to make better use of Ruby on Rails helpers, etc. When I first wrote this I was extremely new to Rails and my unfamiliarity with the framework showsUntil I have the free time to re-write this post, please bear with what is currently here and leave comments to help others that follow after you.
Finally! I’ve been working on this little bit of Ruby code for hours now, all because of some odd bugs (which, when I learn Ruby better, will probably cease to become odd) and a lack of good Ruby on Rails documentation.
What I’ve been working on is getting two related HTML drop-down lists to update properly using the built-in Ajax support in Ruby on Rails. Specifically, when the user selects an Artist from the first drop-down list, only that artist’s Albums should be listed in the second. I wanted to do this without having to retrieve all of the albums during the initial page load and without having to do a post back when the user selects an artist. So, that’s where Ajax comes in. Ajax uses the JavaScript XMLHTTPRequest routine to retrieve new data from the server without requiring the user to refresh the webpage.
Some gotchas for the new Ruby programmer / web developer:
- You cannot modify the InnerHTML of a select drop-down list. Instead, you have to modify the InnerHTML of the div that _contains_ the select drop-down list, and when you do you have to recreate the whole drop-down.
- When you are using instance variables (those that begin with the @-sign), ensure that the instance variable exists before trying to use:
@variable += “value”
syntax or else Ruby will throw up an error. For example, before that statement, add a line that reads:
@variable = “” - When concatenating strings that contain instance variables, Ruby is picky in a way that I can’t fully describe. For example, the following does not work:
@html += “<option value=’” + @album.id + “‘>” + @album.album_name + “</option>”
But this does work:
@html += “<option value=’#{@album.id}’>#{@album.album_name}</option>”
Anyway, this is the troubled code that _did not_ work:
admin_controller.rb
@albums = Album.find_all_by_artist_id(@params["artist_id"])
@html = "<select id='album_id' name='album_id'>"
@html += "<option value=''>No Album</option>"
@albums.each do |@album|
@html += "<option value='" + @album.id + "'>" + @album.album_name + "</option>"
end
@html += "</select>"
After hours I got it working with this code:
admin_controller.rb
@albums = Album.find_all_by_artist_id(@params["artist_id"])
@html = "<select id='album_id' name='album_id'>"
@html += "<option value=''>No Album</option>"
@albums.each do |@album|
@html += "<option value='#{@album.id}'>#{@album.album_name}</option>"
end
@html += "</select>"
But, this has to be coupled with the RHTML code in the template, as follows.
add_song.rhtml
<%= javascript_include_tag "prototype" %>
Artist
<select name="new_song[artist_id]" id="new_song[artist_id]">
<option value="">Select Artist</option>
<% @artists.each do |artist| %>
<option value="<%= artist.id %>">
<%= artist.first_name %> <%= artist.last_name %>
</option>
<% end %>
</select>
Album
<div id="album_id_container">
<select name="new_song[album_id]" disabled="disabled">
<option value="">No Album</option>
</select>
</div>
<%= observe_field("new_song[artist_id]",
:frequency => 0.25,
:update => "album_id_container",
:url => { :action => :add_song_artist },
:with => "'artist_id='+value") %>
19
Models with Associations
Since each song belong to an artist (or multiple artists, depending on how complicated you want to make things), when adding a new song to the database, you want to be able to select the artist from a drop-down list.
In my admin controller, I’ve set up the following:
admin_controller.rb
def add_song
@artists = Artist.find_all
end
This gets me a list of all the artists in the database and stores them in @artists.
Now, in my template then, I can add the following code (adapted from some Recipe example I came across online):
add_song.rhtml
<select name="new_song[artist_id]">
<% @artists.each do |artist| %>
<option value="<%= artist.id %>">
<%= artist.first_name %> <%= artist.last_name %>
</option>
<% end %>
</select>
This will display all of the artists in a drop-down box. Then, when the form is submitted, the id of the artist that is selected (as well as any other fields that you set up) will be accessible through @params["new_song"].
Since each song also belongs to an album, I’d like to have the ability for the user to also select what album the song belongs to when adding the song. Ideally, when an artist is selected, only the albums belonging to that artist would appear in the albums drop-down. To avoid using JavaScript to limit which albums appear, I feel that the form will have to post back to the server in order to accomplish this. So, my next step in getting this lyrics web app going is to figure that out.
19
Setting Up Associations
As my first project with RoR, I’m creating a lyrics website. Thus, there are basically three main models that will have to be maintained through the site: artists, albums, and songs.
So, I’m current in the process of setting up associations between the model classes (Artist, Album, Song) so that I can easily access the associated information. I have no idea if what I’m doing currently is correct, but I’ll probably find out tomorrow when I continue working.
This is what I’ve put into each of the model files so far:
artist.rb
class Artist < ActiveRecord::Base
has_many :songs, :order => "song_name", :dependent => true
has_many :albums, :order => "album_name", :dependent => true
end
album.rb
class Album < ActiveRecord::Base
belongs_to :artist
has_many :songs, :order => "song_title", :dependent => true
end
song.rb
class Song < ActiveRecord::Base
belongs_to :artist
belongs_to :album
end
I have designed the database so that songs do not necessary have to belong to an album, in the case that the album name is not readily available. That's why there's a little bit of redundancy of information.
But, other than that, are any errors apparent to anyone?
19
Late night with Ruby
So I was up til 4am last night with Ruby. I guess I assumed that I’d pick up the language a little easier than I have. Or perhaps I should have just been a little less adventurous and have taken a look at some of the tutorials before jumping into Ruby on Rails head-first.
The first thing I wanted to do with my first project was set up a user authentication system so that I could restrict the creation, modification, and deletion of items to authorized users. Although the Ruby on Rails website has many, many, many different generators that can help people like me get this going quickly, I got completely and utterly confused when doing so. So, after many false starts (during which I tried experimenting with every user authentication generator that the website offered) I took a Counter-Strike break.
After a couple hours of fragging I came back to the project to give it one last go. I settled on just using the simplest generator, Login Generator, and got that working actually quite quickly and easily. I figure I’ll just end up extending this simple user authentication system when I have a better handle on Ruby and Rails. In any case, by 4am when I decided to finally get some sleep, I had gotten the administration area password-protected and had begun playing with adding methods to maintain the various items that my project uses.
So, that’s how my first night with Ruby ended.
When installing the Ruby on Rails framework, I actually found the instructions provided on the Rails site to be a little confusing. To me, it seemed like if I wanted to run the WEBrick web server instead of Apache, that I’d have to find and install the WEBrick webserver myself. But this isn’t the case.
If you are planning on developing on your own computer but are deploying your web application to a host such as TextDrive, then you don’t need to separately download any webserver. What I found out after I had installed Ruby and the Ruby on Rails framework is that the WEBrick webserver had been bundled with Rails and was automatically installed for me. Awesome.
Anyway, if you are looking at installing Rails on Windows, all you need are two files: the Ruby for Windows installation file and the Ruby gems zip file. After you have downloaded both files, you can follow Rails for Windows, lesson 1 to get those both installed and running. You may also want to look at the other lessons if you need to install MySQL or the other tools, but I haven’t (yet) since I already had MySQL installed locally.
There has been so much hype lately on the Internet about Ruby and, specifically, the Ruby on Rails development framework. People just GUSH about how easy and how fast it is to develop web applications.
In any case, yesterday I decided that I wanted to see what all the hype was about and experience Ruby firsthand. As a programmer with experience developing using a number of web scripting languages, I figured picking up a new language couldn’t hurt. Plus, if developing web apps is as fast and easy as people say, then all the better. One interesting feature that I’m looking forward to is that the URLs used throughout Ruby on Rails applications look so user-friendly. No more question marks and ampersands; with Ruby it’s all about the easy-to-read and easy-to-understand directory structure-style query strings.
So far, I’ve installed Ruby and have started up the WEBrick web server to ensure that the installation works. But I’ve yet to write a line of code. I figured I’d get this blog up and running first so that I could detail my experiences with Ruby and Ruby on Rails (RoR) as they happen.
Oh, and to maintain my interest in learning the Ruby language, I’ve _forced_ myself to learn by already signing up for a web hosting plan. Since most hosts don’t seem to offer support for FastCGI or the Ruby on Rails framework, I’ve signed up with TextDrive (the official Ruby host) on their $12/month plan. Hopefully, this will keep me on task and start developing some web apps.
Recommended Services
Recent Posts
- Fantastic new corporate themes for WordPress
- Vistaprint offers FREE t-shirts, too!
- 80+ “Your Ad Here” 125 x 125 banners
- 5 Minute Long Tail SEO Drill: More Traffic, Better SERPs
- iPhone and iPod Touch app statistics: OS adoption, purchasing rates
Recent Comments
- Neerav on Using JavaScript to validate one or more grouped checkboxes
- Jacob on Using JavaScript to validate one or more grouped checkboxes
- kaify on Using JavaScript to validate one or more grouped checkboxes
- JC Goldenstein on How To: Cloak your Affiliate Links for Free in Under 3 Seconds
- Bail Bonds Los Angeles on Amazon Web Services on Rails
Categories
- .net
- acoustic guitar
- affiliate marketing
- ajax
- amazon associates
- blogging
- books
- business ideas
- c#
- code igniter
- dealdotcom
- google adsense
- google adwords
- internet marketing
- iPhone
- javascript
- leadership
- make money online
- mortgage goal
- msn adcenter
- networking
- personal development
- php
- ppc
- ruby
- ruby on rails
- seo
- text-link-ads
- web development
- yahoo search marketing


