<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rory Hansen - Web and mobile app development, affiliate marketing, making money online, and entrepreneurship &#187; ruby on rails</title>
	<atom:link href="http://www.roryhansen.ca/category/web-development/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.roryhansen.ca</link>
	<description>Affiliate marketing, Internet marketing, web development, and small business ideas.</description>
	<lastBuildDate>Wed, 02 Nov 2011 00:49:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>CodeIgniter Blank Page Fix: Blank webpage when setting up CodeIgniter, PHP, MySQL, and Apache</title>
		<link>http://www.roryhansen.ca/2008/10/29/fix-blank-webpage-problems-when-first-setting-up-code-igniter-php-mysql-and-apache/</link>
		<comments>http://www.roryhansen.ca/2008/10/29/fix-blank-webpage-problems-when-first-setting-up-code-igniter-php-mysql-and-apache/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 06:31:07 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[code igniter]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/2008/10/29/fix-blank-webpage-problems-when-first-setting-up-code-igniter-php-mysql-and-apache/</guid>
		<description><![CDATA[Today, I created my first website using the Code Igniter PHP framework and, oh boy, do I like it a lot more than Ruby on Rails. But I&#8217;ll dig into that further in a future post. The purpose of this post is to shed some light on a problem that I wracked my brain over [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I created my first website using the Code Igniter PHP framework and, oh boy, do I like it a lot more than Ruby on Rails. But I&#8217;ll dig into that further in a future post.</p>
<p>The purpose of this post is to shed some light on a problem that I wracked my brain over for a few hours last night.</p>
<p>The problem: <em>After installing Apache, PHP, and MySQL and configuring the Code Igniter framework, you get a blank web page when testing your first controller, model, and view.</em></p>
<p>What I discovered were two issues that, when combined, create the perfect storm of an installation problem:</p>
<ol>
<li>First, <u>MySQL is no longer enabled by default with PHP 5</u>. Says the PHP website of MySQL in PHP 5:<br />
<blockquote><p>MySQL is no longer enabled by default, so the php_mysql.dll DLL must be enabled inside of php.ini. Also, PHP needs access to the MySQL client library. A file named libmysql.dll is included in the Windows PHP distribution and in order for PHP to talk to MySQL this file needs to be available to the Windows systems PATH.</p></blockquote>
<p>It&#8217;s been a LONG time since I&#8217;ve programmed in PHP let alone installed PHP, so this was news to me. Anyway, if check out the <a href="http://ca3.php.net/manual/en/mysql.installation.php">MySQL installation notes</a> on the PHP website if you need help enabling MySQL.  </li>
<li>Unfortunately, that was the easy part. Once I had an error message to work with, Google lead me to the PHP website, and I was in the clear. But, for the longest time, I wasn&#8217;t even getting an error page. Remember, all I was getting was a blank HTML page. So what was the cause? Code Igniter&#8230;</li>
<li>Using some creatively placed <em>die()</em> calls, I found out that the application was dying when trying to connect to the database. (Previous to this, I had already double- and triple-checked my MySQL username and password in the Code Igniter configuration file, and had even tried out alternate accounts, like my MySQL root account.)What I found out was that <u>the MySQL drivers in Code Igniter were suppressing errors when attempting database connections</u>.</li>
</ol>
<p>This is what the code looks like in the Code Igniter mysql_driver.php file:<br />
<code><br />
function db_connect()<br />
{<br />
   if ($this-&gt;port != '')<br />
   {<br />
      $this-&gt;hostname .= ':'.$this-&gt;port;<br />
   }<br />
   return @mysql_connect($this-&gt;hostname, $this-&gt;username, $this-&gt;password, TRUE);<br />
}<br />
</code>The &#8220;@&#8221; symbol before the mysql_connect() function call supresses any errors that may be returned. It is that symbol that wasted a good 2 hours of my life.Anyway, after I removed the &#8220;@&#8221; symbol from the code and re-tested my web application, PHP spit out the error message that I should have been presented with hours ago, and I was well on my way to fixing the problem.<br />
 If you&#8217;re experiencing the same problem that I was, I hope this helps you correct it faster than I did! Best of luck.</p>
<p>Oh, and did I mention how much I prefer Code Igniter over Ruby on Rails? It&#8217;s messier, but with my C and Java background, it makes more sense than Ruby and Ruby on Rails does!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2008/10/29/fix-blank-webpage-problems-when-first-setting-up-code-igniter-php-mysql-and-apache/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Zebra-striped tables using Rails</title>
		<link>http://www.roryhansen.ca/2005/11/30/zebra-striped-tables-using-rails/</link>
		<comments>http://www.roryhansen.ca/2005/11/30/zebra-striped-tables-using-rails/#comments</comments>
		<pubDate>Thu, 01 Dec 2005 02:02:44 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/2005/11/30/zebra-striped-tables-using-rails/</guid>
		<description><![CDATA[Zebra-striped tables are tables where row colors alternate between a light color and a dark color and can be done both using server-side code (ie. Rails) or client-side code (ie. JavaScript). I posted a question asking for the most convenient way to create zebra-striped tables to the Rails newsgroup some weeks ago and the responses [...]]]></description>
			<content:encoded><![CDATA[<p>Zebra-striped tables are tables where row colors alternate between a light color and a dark color and can be done both using server-side code (ie. Rails) or client-side code (ie. JavaScript). I posted a question asking for the most convenient way to create zebra-striped tables to the Rails newsgroup some weeks ago and the responses I received were actually quite scathing. I&#8217;ve normally done this type of thing using server-side code when working with other programming languages (ASP, PHP, JSP, ColdFusion, etc.), but many people feel that this is an extreme no-no (and aren&#8217;t afraid to tell anyone that&#8217;ll listen to them), as it muddles up the separation of business logic from presentation.</p>
<p>Anyway, my point is that, regardless of what others think, I want to continue doing this type of design using server-side code and a recent post on the Code Snippets website highlights a <a rel="nofollow" href="http://www.bigbold.com/snippets/posts/show/924">Rails helper tag called cycle</a> that makes this very convenient. (The name will be familiar for those that have used the Smarty templating engine for PHP.) The cycle tag is exactly the type of suggestion I was looking for when I posted my initial question to the newsgroup. Before that, I&#8217;d been using some nasty combination of if statements and the mod operator to determine the row color and that had completely uglified my code.</p>
<p align="center"><iframe scrolling="no" frameBorder="0" src="http://rcm.amazon.com/e/cm?t=roryonrails-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0977616630&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=cccccc&amp;bg1=FFFFFF&amp;f=ifr" marginHeight="0" marginWidth="0" style="width: 120px; height: 240px"></iframe></p>
<p>This is how you use the <a href="http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M000423" rel="nofollow">cycle helper method</a>:<br />
<code>&lt;tr class="&lt;%= cycle("even", "odd") %&gt;"&gt;<br />
... use item ...<br />
&lt;/tr&gt;</code></p>
<p>You can read more about the <a rel="nofollow" href="http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M000423">cycle helper method in the Rails API</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/11/30/zebra-striped-tables-using-rails/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Amazon Web Services on Rails</title>
		<link>http://www.roryhansen.ca/2005/07/18/amazon-web-services-on-rails/</link>
		<comments>http://www.roryhansen.ca/2005/07/18/amazon-web-services-on-rails/#comments</comments>
		<pubDate>Tue, 19 Jul 2005 01:45:50 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[amazon associates]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/?p=25</guid>
		<description><![CDATA[If you&#8217;re looking to make use of the Amazon Web Services through your Rails app, here&#8217;s a tip: avoid trying to communicate with them using the Ruby on Rails ActiveWebServices classes. I spent a couple hours trying to patch together a solution, but nothing would work. I believe what currently exists is geared towards making [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re looking to make use of the <a href="http://www.amazon.com/gp/browse.html/103-8838522-5067008?%5Fencoding=UTF8&amp;node=3435361">Amazon Web Services</a> through your Rails app, here&#8217;s a tip: avoid trying to communicate with them using the Ruby on Rails <a href="http://api.rubyonrails.com/classes/ActionWebService/Base.html">ActiveWebServices</a> classes. I spent a couple hours trying to patch together a solution, but nothing would work. I believe what currently exists is geared towards making your Rails app accessible through Soap or XMLRPC, rather than consuming exisiting web services.</p>
<p>Instead, use <a href="http://www.caliban.org/ruby/ruby-amazon.shtml">Ruby/Amazon</a>, a &#8220;Ruby language library that allows programmatic access to the popular Amazon Web site via the REST (XML over HTTP) based Amazon Web Services.&#8221; Installation of the library on my development box was a breeze (just read the installation document to learn how) and, plus, it&#8217;s already preinstalled on the servers at TextDrive, so getting going using the Ruby/Amazon library is not a problem at all. For a quick tutorial on how to use the library, check out the <a href="http://www.caliban.org/ruby/ruby-amazon/classes/Amazon.html">documentation on the top-level Amazon module</a> or read <a href="http://gleepglop.com/journal/articles/2005/06/06/amazon-on-rails">this entry</a> on the GleepGlop blog. Both contain examples that show you how to make a basic connection to Amazon through the web services and how to query for products.</p>
<p>Once you get this far, though, you&#8217;ll realize that making calls to the Amazon Web Services with every page view is going to decrease the speed at which your website will render for your users. So what can you do instead? Cache the results in your database, that&#8217;s what. On my lyrics website, I want to have links back to Amazon for every artist that I have lyrics for. So, what I did was create an administrative function that will connect to Amazon and return a list of items for a given artist. This process is repeated over and over so that I have a huge archive of products for each of the artists. Then, instead of querying Amazon with each page view, I just need to call this administrative function every month or so, to update the products in my database.</p>
<p align="center"><iframe src="http://rcm.amazon.com/e/cm?t=roryonrails-20&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596529260&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;m=amazon&#038;lc1=0000FF&#038;bc1=cccccc&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>Below, you&#8217;ll see a body of code that updates all products for all artists whose names begin with a particular letter (for example, &#8220;A&#8221;). For each artist, all existing products are deleted from the database. Then, a new list of products is retrieved and each product is added to the database.</p>
<p>amazon_controller.rb<br />
<code>require 'amazon/search'</p>
<p>class AmazonController &lt; AdminController<br />
   include Amazon::Search</p>
<p>   ASSOCIATES_ID = "amazonaffiliateid-20" # Your Amazon Affiliate ID<br />
   DEV_TOKEN = "0222NLPJQD0A7633Q182" # Your Amazon Web Services Key</p>
<p>   def update<br />
      artists = Artist.find_by_first_letter(@params["letter"])</p>
<p>      artists.each do |artist|<br />
         # Delete all existing "out-dated" products<br />
         existing_products = Product.find_all_by_artist_id(artist.id)<br />
         existing_products.each do |existing_product|<br />
            existing_product.destroy<br />
         end</p>
<p>         # Query Amazon<br />
         request = Request.new(DEV_TOKEN, ASSOCIATES_ID)<br />
         response = request.artist_search(artist.artist_name)<br />
         products = response.products</p>
<p>         # Loop over each product and add them to the database, one at a time<br />
         products.each do |product|<br />
            new_product = Product.new</p>
<p>            new_product.artist_id = artist.id<br />
            new_product.product_name = product.product_name<br />
            new_product.url = product.url<br />
            new_product.image_url_small = product.image_url_small<br />
            new_product.image_url_medium = product.image_url_medium<br />
            new_product.image_url_large= product.image_url_large</p>
<p>            new_product.save<br />
            new_product = nil<br />
         end<br />
      end</p>
<p>      redirect_to(:controller =&lt; "admin", :action =&gt; "index") # Return to the list page if it suceeds<br />
   end<br />
end</code></p>
<p>What I&#8217;d like to do now is to have a Ruby script run nightly that updates a portion of the products in the database. For example, at midnight on the first day of each month, all artists whose names begin with A would have their products updated from Amazon. At midnight on day two, all B artists would have their products updated. I just have to figure out how to do this&#8230; but once I do, I&#8217;ll post it here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/07/18/amazon-web-services-on-rails/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Implementing Search in Ruby on Rails</title>
		<link>http://www.roryhansen.ca/2005/07/07/implementing-search-in-ruby-on-rails/</link>
		<comments>http://www.roryhansen.ca/2005/07/07/implementing-search-in-ruby-on-rails/#comments</comments>
		<pubDate>Fri, 08 Jul 2005 04:23:10 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/?p=20</guid>
		<description><![CDATA[Update: While searching like this works, it&#8217;s probably not the most efficient way. In the near future I&#8217;ll be looking into setting up Ruby/Odeum, which is a ruby binding to the QDBM Odeum inverted index library. Basically, every night a new search index would be generated, and searching would be done over this index, rather [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> While searching like this works, it&#8217;s probably not the most efficient way. In the near future I&#8217;ll be looking into setting up <a href="http://www.zedshaw.com/projects/ruby_odeum/index.html">Ruby/Odeum</a>, which is a ruby binding to the QDBM Odeum inverted index library. Basically, every night a new search index would be generated, and searching would be done over this index, rather than dynamically over the database. This should greately improve performance. But until then, this is what I&#8217;m using &#8230;</p>
<hr/>
<p>I found this <a href="http://ifup.org/2005/04/02/ajax-and-ruby-on-rails-until-5am/">great post</a> on Brandon Philips blog, which showed an example of how to search your database for relevant data, given a search string from the user. He got his inspiration from <a href="http://typo.leetsoft.com/trac.cgi/browser/trunk/">Tobias&#8217; typo source tree</a>, and, in turn, so did I. (Actually, mine is basically the exact same search, with some of the database column names changed. Thanks Tobias.)</p>
<p>song.rb<br />
<code>def self.search(query)<br />
   if !query.to_s.strip.empty?<br />
      tokens = query.split.collect {|c| "%#{c.downcase}%"}<br />
      find_by_sql(["select s.* from songs s where #{ (["(lower(s.song_title) like ? or lower(s.song_lyrics) like ?)"] * tokens.size).join(" and ") } order by s.created_on desc", *(tokens * 2).sort])<br />
   else<br />
      []<br />
   end<br />
end</code></p>
<p>Once you&#8217;ve added the search method to your model, it&#8217;s even simpler to use.</p>
<p>search_controller.rb<br />
<code>def songs<br />
   @query = @params["query"]<br />
   @songs = Song.search(@query)<br />
end</code></p>
<p>You&#8217;ll notice that I&#8217;m saving the search query into an instance variable called @query. This is so that I can output the query back to the user on the search results page, phrased like, <em>Search results for &#8220;search query here&#8221;</em>. If you&#8217;re going to do the same, don&#8217;t forget to sanitize the search query manually, or escape the HTML like so:</p>
<p><code>&lt;%=h @query %&gt;</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/07/07/implementing-search-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails find_all Example</title>
		<link>http://www.roryhansen.ca/2005/07/03/ruby-on-rails-find_all-example/</link>
		<comments>http://www.roryhansen.ca/2005/07/03/ruby-on-rails-find_all-example/#comments</comments>
		<pubDate>Mon, 04 Jul 2005 04:19:33 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/?p=16</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>In an <a href="http://www.roryhansen.ca/?p=14">earlier blog post</a>, 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.</p>
<p>artist.rb (old code)<br />
<code>def self.find_by_first_letter(letter = "A")<br />
Â Â Â find_by_sql ["select a.* from artists a where ucase(left(artist_name, 1)) = ?", letter]<br />
end</code></p>
<p>artist.rb (new code)<br />
<code>def self.find_by_first_letter(letter = "A")<br />
Â Â Â find_all ["ucase(left(artist_name, 1)) = ?", letter]<br />
end</code></p>
<p align="center"><iframe scrolling="no" frameBorder="0" src="http://rcm.amazon.com/e/cm?t=roryonrails-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0977616630&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=cccccc&amp;bg1=FFFFFF&amp;f=ifr" marginHeight="0" marginWidth="0" style="width: 120px; height: 240px"></iframe></p>
<p>I think using the find_all function instead of the find_by_sql function follows the &#8220;Ruby on Rails way&#8221; more closely. Plus, it&#8217;s shorter and, perhaps, easier to understand for people who aren&#8217;t familiar with SQL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/07/03/ruby-on-rails-find_all-example/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails find_by_sql Example</title>
		<link>http://www.roryhansen.ca/2005/07/01/ruby-on-rails-find_by_sql-example/</link>
		<comments>http://www.roryhansen.ca/2005/07/01/ruby-on-rails-find_by_sql-example/#comments</comments>
		<pubDate>Fri, 01 Jul 2005 16:14:14 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/?p=14</guid>
		<description><![CDATA[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&#8217;m developing, I&#8217;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&#8217;s name begins [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note:</strong> Read <a href="http://www.roryhansen.ca/?p=16">this post</a> to learn how to implement the same method using the find_all function. <em>- Rory, July 3, 2005</em></p>
<p>In the lyrics website I&#8217;m developing, I&#8217;d like to be able to use URLs like this in my administrative back-end:</p>
<p>http://www.website.com/admin/artists/list/A</p>
<p>where, when I visit this URL, a list of artists who&#8217;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.</p>
<p>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.</p>
<p>artist.rb<br />
<code>class Artist &lt; ActiveRecord::Base<br />
   has_many :songs, :order =&gt; "song_title", :dependent =&gt; true<br />
   has_many :albums, :order =&gt; "album_name", :dependent =&gt; true</p>
<p>def self.find_by_first_letter(letter = "A")<br />
      find_by_sql ["select * from artists where ucase(left(artist_name, 1)) = ?", letter]<br />
   end<br />
end<br />
</code></p>
<p>As you can see, the method find_by_first_letter takes in an argument called &#8220;letter&#8221; and uses this argument in the function call to find_by_sql. You&#8217;ll notice that a question mark appears in the SQL statement where we would actually like the value associated with &#8220;letter&#8221; 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 <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</p>
<p align="center"><iframe scrolling="no" frameBorder="0" src="http://rcm.amazon.com/e/cm?t=roryonrails-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0977616630&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=cccccc&amp;bg1=FFFFFF&amp;f=ifr" marginHeight="0" marginWidth="0" style="width: 120px; height: 240px"></iframe></p>
<p>Then, in our action, all we have to do is call our new method.</p>
<p>admin_controller.rb<br />
<code>@artists = Artist.find_by_first_letter(@params["letter"])</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/07/01/ruby-on-rails-find_by_sql-example/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Related Drop-down Lists with Ruby on Rails and AJAX</title>
		<link>http://www.roryhansen.ca/2005/06/21/related-drop-down-lists-with-ruby-and-ajax/</link>
		<comments>http://www.roryhansen.ca/2005/06/21/related-drop-down-lists-with-ruby-and-ajax/#comments</comments>
		<pubDate>Tue, 21 Jun 2005 18:57:29 +0000</pubDate>
		<dc:creator>Rory</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.roryhansen.ca/?p=9</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>Note:</strong> 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.</p></blockquote>
<p>Finally! I&#8217;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.</p>
<p>What I&#8217;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&#8217;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&#8217;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.</p>
<p align="center" style="text-align: center"><iframe scrolling="no" frameBorder="0" src="http://rcm.amazon.com/e/cm?t=roryonrails-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0596527446&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=FFFFFF&amp;bg1=FFFFFF&amp;f=ifr" marginHeight="0" marginWidth="0" style="width: 120px; height: 240px; border: #cccccc 1px solid"></iframe></p>
<p>Some gotchas for the new Ruby programmer / web developer:</p>
<ul>
<li>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.</li>
<li>When you are using instance variables (those that begin with the @-sign), ensure that the instance variable exists before trying to use:<br />
@variable += &#8220;value&#8221;<br />
syntax or else Ruby will throw up an error. For example, before that statement, add a line that reads:<br />
@variable = &#8220;&#8221;</li>
<li>When concatenating strings that contain instance variables, Ruby is picky in a way that I can&#8217;t fully describe. For example, the following does not work:<br />
@html += &#8220;&lt;option value=&#8217;&#8221; + @album.id + &#8220;&#8216;&gt;&#8221; + @album.album_name + &#8220;&lt;/option&gt;&#8221;<br />
But this does work:<br />
@html += &#8220;&lt;option value=&#8217;#{@album.id}&#8217;&gt;#{@album.album_name}&lt;/option&gt;&#8221;</li>
</ul>
<p>Anyway, this is the troubled code that _did not_ work:</p>
<p>admin_controller.rb<br />
<code>@albums = Album.find_all_by_artist_id(@params["artist_id"])<br />
@html = "&lt;select id='album_id' name='album_id'&gt;"<br />
@html += "&lt;option value=''&gt;No Album&lt;/option&gt;"<br />
@albums.each do |@album|<br />
   @html += "&lt;option value='" + @album.id + "'&gt;" + @album.album_name + "&lt;/option&gt;"<br />
end<br />
@html += "&lt;/select&gt;"</code></p>
<p>After hours I got it working with this code:</p>
<p>admin_controller.rb<br />
<code>@albums = Album.find_all_by_artist_id(@params["artist_id"])<br />
@html = "&lt;select id='album_id' name='album_id'&gt;"<br />
@html += "&lt;option value=''&gt;No Album&lt;/option&gt;"<br />
@albums.each do |@album|<br />
   @html += "&lt;option value='#{@album.id}'&gt;#{@album.album_name}&lt;/option&gt;"<br />
end<br />
@html += "&lt;/select&gt;"</code></p>
<p>But, this has to be coupled with the RHTML code in the template, as follows.</p>
<p>add_song.rhtml<br />
<code>&lt;%= javascript_include_tag "prototype" %&gt;</p>
<p>Artist<br />
&lt;select name="new_song[artist_id]" id="new_song[artist_id]"&gt;<br />
   &lt;option value=""&gt;Select Artist&lt;/option&gt;<br />
   &lt;% @artists.each do |artist| %&gt;<br />
      &lt;option value="&lt;%= artist.id %&gt;"&gt;<br />
         &lt;%= artist.first_name %&gt; &lt;%= artist.last_name %&gt;<br />
      &lt;/option&gt;<br />
   &lt;% end %&gt;<br />
&lt;/select&gt;</p>
<p>Album<br />
&lt;div id="album_id_container"&gt;<br />
   &lt;select name="new_song[album_id]" disabled="disabled"&gt;<br />
      &lt;option value=""&gt;No Album&lt;/option&gt;<br />
   &lt;/select&gt;<br />
&lt;/div&gt;</p>
<p>&lt;%= observe_field("new_song[artist_id]",<br />
   :frequency =&gt; 0.25,<br />
   :update =&gt; "album_id_container",<br />
   :url =&gt; { :action =&gt; :add_song_artist },<br />
   :with =&gt; "'artist_id='+value") %&gt;</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.roryhansen.ca/2005/06/21/related-drop-down-lists-with-ruby-and-ajax/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
	</channel>
</rss>

