<?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>for(;;){ blog }</title>
	<atom:link href="http://blog.ngriffith.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ngriffith.com</link>
	<description>“Computers are useless.  They can only give you answers.” --Pablo Picasso</description>
	<lastBuildDate>Mon, 29 Jun 2009 21:31:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Polymorphic Join Tables</title>
		<link>http://blog.ngriffith.com/2009/06/polymorphic-join-tables/</link>
		<comments>http://blog.ngriffith.com/2009/06/polymorphic-join-tables/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 07:44:01 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[Web Design]]></category>
		<category><![CDATA[polymorphism]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.ngriffith.com/?p=83</guid>
		<description><![CDATA[While working on a recent Rails project, I came across the need for a number of polymorphic relationships between models. If you&#8217;re not familiar with polymorphisms, a great Railscast can be found here. The inspiration for most of my work came from a helpful tutorial found here.
The problem I encountered involved a feature which would [...]]]></description>
			<content:encoded><![CDATA[<p>While working on a recent Rails project, I came across the need for a number of polymorphic relationships between models. If you&#8217;re not familiar with polymorphisms, a great Railscast can be found <a title="Railscast #154" href="http://railscasts.com/episodes/154-polymorphic-association" target="_blank">here</a>. The inspiration for most of my work came from a helpful tutorial found <a href="http://m.onkey.org/2007/8/14/excuse-me-wtf-is-polymorphs">here</a>.</p>
<p>The problem I encountered involved a feature which would allow the sending of &#8220;notices&#8221; to users of the site, such that when a user logs in, they can be notified of things by an admin or by other users. A naïve approach would be to simply use a many-to-many relationship between notices and users. However, since users can be accessed through a few other models, I decided to implement a more robust notification system.</p>
<p>Already included in the application is the ability for an admin to create &#8220;roles&#8221; and &#8220;departments&#8221; and assign users to them. What I wanted was the ability to create a notice and assign it to all users in a given role or department, as well as to individual users. This may have required three separate join tables, but with a few tricks I was able to reduce it to one. It&#8217;s important to note that as of now, Rails <strong>cannot</strong> handle both polymorphic relations and the &#8220;has_many :through&#8221; feature. It attempts to create a broken SQL query, and spits out a confusing error. So instead, I went with the plugin <strong>has_many_polymorphs</strong>.</p>
<p>Here&#8217;s what my code looks like:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> CreateNoticesUserSources &lt; <span class="re2">ActiveRecord::Migration</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">up</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; create_table <span class="re3">:user_sinks_user_sources</span> <span class="kw1">do</span> |t|</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; t.<span class="me1">references</span> <span class="re3">:notice</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; t.<span class="me1">references</span> <span class="re3">:user_source</span>, <span class="re3">:polymorphic</span> =&gt; <span class="kw2">true</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">down</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; drop_table <span class="re3">:notices_user_sources</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> NoticesUserSources &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:user_source</span>, <span class="re3">:polymorphic</span> =&gt; <span class="kw2">true</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:notice</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> User &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;has_many_polymorphs <span class="re3">:user_sources</span>, <span class="re3">:from</span> =&gt; <span class="br0">&#91;</span><span class="re3">:departments</span>, <span class="re3">:roles</span>, <span class="re3">:users</span><span class="br0">&#93;</span>, <span class="re3">:through</span> =&gt; <span class="re3">:notices_user_sources</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> Department &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> Role &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> User &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">def</span> users</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#91;</span><span class="kw2">self</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>Notice that in the User model, I define the &#8220;users&#8221; method as an array of the user itself. I do this because we are treating the User model as a &#8220;user source,&#8221; meaning user.users should return a list of users available to the notice, much like department.users and role.users should. This is a small hack, but allows me to simplify my code later on.</p>
<p>Now that we&#8217;ve set up this polymorphic association, I can give the array &#8220;notice.user_sources&#8221; any combination of departments, roles, and users. I can also use &#8220;notice.departments&#8221;, &#8220;notice.roles&#8221;, and &#8220;notice.users&#8221; to access the subsets of &#8220;user_sources.&#8221;</p>
<p>Returning a list of unique users assigned to a notice is as simple as writing:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">notice.<span class="me1">user_sources</span>.<span class="me1">collect</span><span class="br0">&#123;</span>|s| s.<span class="me1">users</span><span class="br0">&#125;</span>.<span class="me1">flatten</span>.<span class="me1">uniq</span></div>
</li>
</ol>
</div>
<p>The reverse is slightly more complicated (and should probably be implemented in a method in the user model):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="br0">&#40;</span>user.<span class="me1">department</span>.<span class="me1">notices</span> + user.<span class="me1">roles</span>.<span class="me1">collect</span><span class="br0">&#123;</span>|r| r.<span class="me1">notices</span><span class="br0">&#125;</span> + user.<span class="me1">notices</span><span class="br0">&#41;</span>.<span class="me1">flatten</span>.<span class="me1">uniq</span></div>
</li>
</ol>
</div>
<p>After getting this set-up, I realized that there were other models (notably &#8220;restrictions&#8221; and &#8220;requests&#8221;) that should also have a similar relationship with the User model. I could have created a separate set of polymorphic realtionships for each of those models, but instead I decided to create a double join between &#8220;user sources&#8221; (users, departments, and roles) and &#8220;user sinks&#8221; (notices, restrictions, and reqeusts). Thankfully, <strong>has_many_polymorphs</strong> provides a very simple way of doing this:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> UserSinksUserSource &lt; <span class="re2">ActiveRecord::Base</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:user_source</span>, <span class="re3">:polymorphic</span> =&gt; <span class="kw2">true</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:user_sink</span>, &nbsp; <span class="re3">:polymorphic</span> =&gt; <span class="kw2">true</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; acts_as_double_polymorphic_join<span class="br0">&#40;</span><span class="re3">:user_sources</span> =&gt;<span class="br0">&#91;</span><span class="re3">:departments</span>,:roles,:users<span class="br0">&#93;</span>, <span class="re3">:user_sinks</span> =&gt;<span class="br0">&#91;</span><span class="re3">:restrictions</span>,:requests,:notices<span class="br0">&#93;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
</ol>
</div>
<p>The rest follows as one would expect, with polymorphic relationships set up on both ends.</p>
<p>While the double polymorphic join may be more than you would need for most applications (I certainly could have managed without it), it&#8217;s nice to know that that kind of functionality is so easy to implement.</p>
<p>One last note, though:<br />
The <strong>has_many_polymorphs</strong> plugin works well for most purposes, but isn&#8217;t a completely pure polymorphic join &#8212; it instead defines some hidden methods and performs a few more steps than would ideally be necessary, in order to circumvent the problems rails has with &#8220;has_many :through&#8221; and polymorphisms. If you set <em>ENV[‘HMP_DEBUG’]</em> to true, you&#8217;ll be able to see what is actually going on underneath. It also wouldn&#8217;t be too difficult to write similar functionality without the use of this plugin, but it would just add more clutter to the models.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ngriffith.com/2009/06/polymorphic-join-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Heroku: Rails in the Cloud</title>
		<link>http://blog.ngriffith.com/2008/11/getting-started-with-heroku-or-ruby-on-rails-in-the-cloud/</link>
		<comments>http://blog.ngriffith.com/2008/11/getting-started-with-heroku-or-ruby-on-rails-in-the-cloud/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 23:23:02 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.ngriffith.com/sample/?p=3</guid>
		<description><![CDATA[I recently received an excited email from one of my summer colleagues about a new web start-up called "Heroku." Essentially, Heroku allows users to develop and test Rails applications from a web interface, keeping all of the essential Rails features and application files accessible and editable from the browser. In addition, users can work locally and update their projects with the Git version control system. The projects are hosted for free by Heroku (potentially with payed subscriptions once it is out of beta), so getting an application up and running is pretty effortless.]]></description>
			<content:encoded><![CDATA[<div id="attachment_23" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.ngriffith.com/wp-content/uploads/2008/11/heroku-cloud.jpg"><img class="size-medium wp-image-23" title="heroku-cloud" src="http://blog.ngriffith.com/wp-content/uploads/2008/11/heroku-cloud-300x218.jpg" alt="Rails + Cloud Computing = Heroku" width="300" height="218" /></a><p class="wp-caption-text">Ruby on Rails + Cloud Computing = Heroku</p></div>
<p>This past summer, I landed a job writing web applications in Ruby on Rails. I had no Rails experience beforehand, but I soon realized how intuitive and enjoyable Rails can be. I was learning to organize my code more effectively by simply learning how to use the Rails framework. By the end of the summer, I had fallen in love with Rails.</p>
<p>I recently received an excited email from a summer colleague regarding a new web start-up called &#8220;Heroku.&#8221; In a nutshell, <a title="Heroku" href="http://www.heroku.com" target="_blank">Heroku</a> allows users to develop and test Rails applications from a web interface, keeping everything accessible and editable from the browser. In addition, users can work locally and update their projects with the Git version control system. The projects are hosted for free by Heroku (potentially with paid subscriptions once it is out of beta), so getting an application up and running is pretty effortless.</p>
<div id="attachment_25" class="wp-caption aligncenter" style="width: 360px"><a href="http://blog.ngriffith.com/wp-content/uploads/2008/11/heroku.png"><img class="size-full wp-image-25" title="heroku" src="http://blog.ngriffith.com/wp-content/uploads/2008/11/heroku.png" alt="Heroku apps can be developed from within a web browser." width="350" height="235" /></a><p class="wp-caption-text">Heroku apps can be developed from within a web browser.</p></div>
<p>I&#8217;ve started hosting some of my apps on Heroku. Perhaps Heroku&#8217;s web interface will see some updates, but right now I find it clunky and often annoyingly slow. Instead, I prefer local edits, because once set up, navigating files and code is much faster on my laptop, and I don&#8217;t have to be online to develop my application. The following tutorial should explain how to get started with Heroku and work on Rails applications from a local machine.</p>
<p><strong>But first&#8230;</strong></p>
<p>Unless you&#8217;ve been trapped in some sort of time paradox for the past couple years and have just now emerged, you&#8217;ve probably heard of Ruby on Rails. However, if you have no idea how a Rails application works, I would recommend checking out some of the tutorials on the <a title="Ruby on Rails" href="http://www.rubyonrails.org/" target="_blank">Rails Homepage</a>. Otherwise, keep reading, and start experimenting with your own Heroku-hosted Rails application.</p>
<p><em>Note: At this point, I will assume that you have familiarized yourself with Rails and have at least installed Rails and RubyGems. </em></p>
<p><em>Windows Users: You may need to play around to get this tutorial working in your command prompt. In fact, it may not be possible yet to work locally from Windows. I&#8217;m currently writing this tutorial from Ubuntu, but it should work in OS X as well.</em></p>
<p><strong>Step 1: Sign up for an account<br />
</strong></p>
<p>Go to heroku.com, hit &#8220;login&#8221; and then click on &#8220;sign up.&#8221; There is currently a waiting list, which for me took about 10 minutes. However, if you find yourself waiting a long time, leave a comment asking for an invite and I&#8217;ll try to get you one.</p>
<p><strong>Step 2: Install and configure the Heroku gem<br />
</strong></p>
<p>You can use Heroku&#8217;s web interface to create a new app and begin editing it. However, I prefer using the Heroku gem, which allows you to have full functionality from your local machine. To begin, go to your Mac or Linux terminal and type the following (Ubuntu users may need to add &#8220;sudo&#8221;):</p>
<blockquote><p>gem install heroku</p></blockquote>
<p>This should install the Heroku gem. At this point, you may need to configure your ssh to use RSA authentication. Run the following command:</p>
<blockquote><p>ssh-keygen -t rsa</p></blockquote>
<p>It should prompt you to save a file, which should look something like &#8220;/home/[username]/.ssh/id_rsa&#8221; (go ahead and type that in). This will create an RSA authentication file for accessing Heroku&#8217;s servers.</p>
<p>The Heroku gem should now be configured. Go ahead and type the command &#8220;heroku list&#8221; to test it out.</p>
<p><strong>Step 3: Create a new Heroku app</strong></p>
<p>Create the application on Heroku&#8217;s servers by running the following command:</p>
<blockquote><p>heroku create [appname]</p></blockquote>
<p>This should return the following line:</p>
<blockquote><p>Created http://[appname].heroku.com/ |</p>
<p>git@heroku.com:[appname].git</p></blockquote>
<p>Your application exists online at the returned URL. Take note of the Git address, as we&#8217;ll use it in the next step.</p>
<p><div id="attachment_27" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.ngriffith.com/wp-content/uploads/2008/11/welcome-aboard.png"><img class="size-medium wp-image-27" title="welcome-aboard" src="http://blog.ngriffith.com/wp-content/uploads/2008/11/welcome-aboard-300x181.png" alt="Test your app at [appname].heroku.com" width="300" height="181" /></a><p class="wp-caption-text">Test your app at (appname).heroku.com</p></div><strong>Step 4: Get a local copy running</strong></p>
<p>Run the following command to copy your new application&#8217;s files to a local folder:</p>
<blockquote><p>git clone git@heroku.com:[appname].git</p></blockquote>
<p>This should set up a git repository in the folder &#8220;appname&#8221;, which will allow you to update files from both Heroku&#8217;s web interface and from your local machine. You could instead use the command &#8220;heroku clone&#8221; rather than &#8220;git clone,&#8221; but they both use &#8220;git,&#8221; so you may as well use the version control system directly.</p>
<p><strong>Step 5: Start editing your application</strong></p>
<p>Yep, that&#8217;s it. You should be ready to get things running at this point. Go ahead and start editing your application in TextMate, RadRails, gedit, or whichever text editor you prefer. You can also copy files over from another Rails application, if you are trying to get an existing app running on Heroku. To upload your local files to Heroku, make sure you have changed to your application&#8217;s directory (&#8220;&#8230;/[appname]/&#8221;) and type the following commands:</p>
<blockquote><p>git add .<br />
git commit -m &#8220;type your changes here&#8221;<br />
git push</p></blockquote>
<p>If you make changes with the Heroku web editor, you can download the files with the following command:</p>
<blockquote><p>git pull</p></blockquote>
<p>At this point, you should be able to use both sets of commands to keep your Rails application up-to-date between your computer and Heroku, or even across different computers.</p>
<p><strong>Last Step (optional):</strong></p>
<p>To make your application publicly available, run the following command.</p>
<blockquote><p>heroku update myapp &#8211;public true &#8211;mode production</p></blockquote>
<p>This will put your application in production mode. Heroku won&#8217;t allow any edits, but your application will run much faster.</p>
<p><strong>Concluding Remarks:</strong></p>
<p>The &#8220;gem&#8221; and &#8220;heroku&#8221; commands have many other features, all of which are worth exploring. For instance, once you have an application in production mode, you might find it useful to create a new Git branch for development purposes. You can synchronize it with a new Heroku app in development mode. When you are done developing on the branch, you can merge it back into your production application. All of this would take some complicated Git work beyond the scope of this tutorial.</p>
<p>Heroku seems very promising, and, while it&#8217;s certainly not the only service of its kind, it is definitely pushing the boundaries of web development. Hopefully we&#8217;ll begin to see even more sites focusing on cloud computing, as the potential uses have certainly not run dry.</p>
<p>For now, I really recommend giving Heroku a try, and if you haven&#8217;t yet fallen in love with Rails, go ahead and spend a few hours reading into it. Perhaps you&#8217;ll be as intrigued as I was. Perhaps not. Either way, Rails is definitely going to be around for a while.</p>
<h3>EDIT:</h3>
<p>Some of this tutorial is now outdated. Much of the functionality described has been relocated to <a href="http://herokugarden.com/">Heroku Garden</a>, while <a href="http://heroku.com/">Heroku</a> only uses Git. I would recommend reading the &#8220;Docs&#8221; page on Heroku for more recent info.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ngriffith.com/2008/11/getting-started-with-heroku-or-ruby-on-rails-in-the-cloud/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
