<?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>Alex Bisignano</title>
	<atom:link href="http://alx.bz/feed/" rel="self" type="application/rss+xml" />
	<link>http://alx.bz</link>
	<description></description>
	<lastBuildDate>Wed, 07 Mar 2012 01:39:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>AJAX on Rails: Ajaxified Create and Destroy Actions for has_many / belongs_to related Models</title>
		<link>http://alx.bz/2012/03/06/ajax-on-rails-ajaxified-create-and-destroy-actions-for-has_manybelongs_to-related-models/</link>
		<comments>http://alx.bz/2012/03/06/ajax-on-rails-ajaxified-create-and-destroy-actions-for-has_manybelongs_to-related-models/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 01:38:49 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Programming]]></category>

		<guid isPermaLink="false">http://alx.bz/?p=403</guid>
		<description><![CDATA[<p><img width="300" height="233" src="http://alx.bz/wp-content/uploads/2012/03/rails-e1331084147626-300x233.jpg" class="attachment-medium wp-post-image" alt="OLYMPUS DIGITAL CAMERA" title="OLYMPUS DIGITAL CAMERA" /></p>This post is about how to implement some quick AJAX functionality on Rails so that simple nested models can be Created and Destroyed without having to refresh the page.]]></description>
			<content:encoded><![CDATA[<p><img width="300" height="233" src="http://alx.bz/wp-content/uploads/2012/03/rails-e1331084147626-300x233.jpg" class="attachment-medium wp-post-image" alt="OLYMPUS DIGITAL CAMERA" title="OLYMPUS DIGITAL CAMERA" /></p><p>It&#8217;s been about 8 months since I made the switch from PHP to Ruby. Now about 80% of all my web programming work is done in Ruby, and I&#8217;m much more quickly able to build complex applications.</p>
<p>HOWEVER: I hate Ruby. I love Rails. Maybe it&#8217;s because I originally learned to code in Java and I&#8217;m <em>still</em> uncomfortable with Ruby&#8217;s syntax? IDK. W/E. Rails is great.</p>
<p>Today&#8217;s post is about how to implement some quick AJAX functionality on Rails so that simple nested models can be Created and Destroyed without having to refresh the page.</p>
<h3>The Setting for Our Story</h3>
<p>I recently built a CMS for diseases, mutations and a whole other lot of information for <a title="Recombine" href="http://recombine.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/recombine.com?referer=');">Recombine</a>. One of our models is the Disease model:</p>
<p><strong><code>disease.rb</code></strong><br />
<code><br />
...<br />
has_many :references</p>
<p>def to_param<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;permalink<br />
end<br />
...<br />
</code></p>
<p>Notice that I have defined to_param as the permalink for the disease model. I&#8217;ve decided that I want the URLs to be custom as I&#8217;ve <a href="http://alx.bz/2011/08/24/ruby-on-rails-customized-urls-for-user-profile-show-pages/" target="_blank">previously explained how to do</a>. The model we will be using AJAX on that belongs to a Disease is the Reference (as in a reference within scientific literature) model:</p>
<p><strong><code>reference.rb</code></strong><br />
<code><br />
...<br />
belongs_to :disease<br />
...<br />
</code></p>
<p>Finally, we can specify the resources available via the Routes file:</p>
<p><strong><code>routes.rb</code></strong><br />
<code><br />
...<br />
resources :diseases do<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resources :references, <img src='http://alx.bz/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly => [:create, :destroy]<br />
end<br />
resources :references, <img src='http://alx.bz/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly => [:create, :destroy]<br />
...<br />
</code></p>
<p>Notice that we are only adding the Create and Destroy actions for our References Controller. With this stage set, our goal is to establish our application so that, for a given disease, all disease information and associated references are viewable from the <code>views/diseases/view.html.erb</code> file, and that editing the disease information, or adding/removing associated references, can all be accomplished from the <code>views/diseases/edit.html.erb</code> file. <i>Note: I have not included a description of the migrations/table/columns structure. You can assume whatever fields exist, and know with certainty that the reference table has a <code>disease_id</code> column.</i></p>
<h3>Setting Up Our Controllers</h3>
<p>The Diseases Controller is going to be fairly typical with most RESTful actions available. The References Controller, is only going to have two RESTful actions, and both will only respond to javascript requests.</p>
<p><strong><code>diseases_controller.rb</code></strong><br />
<code><br />
class DiseasesController < ApplicationController</p>
<p>...</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_filter :authenticate, :except => [:index, :show]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_filter :admin_user, :except => [:index, :show]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def index<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@diseases = Disease.all<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@title = "All Diseases"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def show<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@disease = Disease.find_by_permalink(params[:id])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@references = Disease.references<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@title = Disease.name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def edit<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@disease = Disease.find_by_permalink(params[:id])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@references = Disease.references<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@title = Disease.name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@reference = Reference.new<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end</p>
<p>...</p>
<p>end<br />
</code></p>
<p>Note that the other RESTful actions are all there, but I&#8217;m only displaying the Show and Edit actions as they are all we really are working with for this post. Also note the instance variable <code>@reference</code> is declared in the Edit action so that we may create new references from the Disease Edit page. Now for the References Controller:</p>
<p><strong><code>references_controller.rb</code></strong><br />
<code><br />
class ReferencesController < ApplicationController</p>
<p>...</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_filter :authenticate<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;before_filter :admin_user</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def create<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@reference = Reference.new(params[:reference]) #Params from form<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@reference.save<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@response = @reference.errors #Errors<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@references = Reference.where(:disease_id => params[:reference][:disease_id]).all<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@disease = Disease.find_by_id(params[:reference][:disease_id])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;respond_to do |format|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format.js {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def destroy<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reference.find_by_id(params[:id]).destroy<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@disease = Disease.find_by_id(params[:disease_id])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@references = @disease.references<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;respond_to do |format|<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format.js {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end</p>
<p>...</p>
<p>end<br />
</code></p>
<p>Notice that in the Create action, a reference is created from the <code>params[:reference]</code> parameters. These are going to be passed to our controller from our AJAXified References form located in the <code>views/diseases/edit.html.erb</code> file. Also notice that we re-delcare the <code>@diseases</code> and <code>@references</code> instance variables in the create action. This is important for when we update our <code>_reference_list.html.erb</code> partial within the main page.</p>
<p>In the Destroy action, we are simply sending along the <code>id</code> of the reference that we wish to destroy via AJAX. However, in order to properly re-render the (forthcoming) <code>_reference_list.html.erb</code> partial, we also need to send over a <code>disease_id</code> parameter so that we can then re-declare the <code>@disease</code> and <code>@references</code> instance variables for the partial. If you didn&#8217;t follow that, don&#8217;t worry, it will become clear once we see the views.</p>
<h3>The Views to Put it Together</h3>
<p>The <code>views/diseases/show.html.erb</code> view is going to be a pretty standard run through the <code>@disease</code> and <code>@references</code> instance variables. However, the <code>views/diseases/edit.html.erb</code> is where all of the AJAX magic will occur. Let&#8217;s look at the <code>views/diseases/edit.html.erb</code> view first:</p>
<p><strong><code>views/diseases/edit.html.erb</code></strong><br />
<code><br />
#Make the form_for function for the disease model data<br />
<%= form_for @disease do |f| %><br />
...<br />
<%= f.submit :value => "Update Disease" %><br />
<% end %></p>
<p>#Render the reference list<br />
&lt;ul class="reference_list"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= render 'references/reference_list' %><br />
&lt;/ul&gt;</p>
<p>#Make the new reference form<br />
<%= form_for @reference, :remote => true do |f| %><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= f.hidden_field :disease_id, :value => @disease.id %><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= f.text_area :info, :class => "reference_info" %><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= f.submit :value => "Add Reference" %><br />
<% end %></p>
<p></code></p>
<p>You can see that we have passed the hidden field <code>disease_id</code> on the reference form as we had anticipated needing in the controller. Before we take a look at what submitting the form does, let&#8217;s first look at our reference list partial:</p>
<p><strong><code>views/references/_reference_list.html.erb</code></strong><br />
<code><br />
<% @references.each do |r| %><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= r.info %><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%= link_to reference_path(r, :disease_id => @disease.id), :method => :delete, :confirm => 'Delete this Reference?', :remote => true do |l| %>Delete<% end %><br />
<% end %><br />
</code></p>
<p>Notice that we have generated a <code>link_to</code> tag for each reference that marks a Delete action for that reference. The Delete Action in the References Controller will remove the associated reference upon clicking the link (after clicking okay to associated confirmation message). Now only two thins are left to do: <code>views/references/create.js.erb</code> and <code>views/references/destroy.js.erb</code>. Javascript must be used to update the reference list each time a create or destroy action is called from the <code>views/diseases/edit.html.erb</code> view.</p>
<p><strong><code>views/references/create.js.erb</code></strong><br />
<code><br />
//The first line updates the reference list (with the new Reference).<br />
$('ul.reference_list').html("<%= escape_javascript(render('references/reference_list')) %>");</p>
<p>//This second line removes the text that was within the textarea (looks nicer and avoids duplication).<br />
$('textarea.reference_info').val("");<br />
</code></p>
<p><strong><code>views/references/destroy.js.erb</code></strong><br />
<code><br />
//Here we only need to re-render the reference list after the destroy action is done.<br />
$('ul.reference_list').html("<%= escape_javascript(render('references/reference_list')) %>");<br />
</code></p>
<p>Whew. That took a lot to accomplish such a simple concept. Not sure it was the best way to go about doing so, but it&#8217;s up and working. Would love to hear from anyone if there&#8217;s a simpler way within rails to accomplish this sort of effect. Good luck to those playing around with AJAX on Rails!</p>
]]></content:encoded>
			<wfw:commentRss>http://alx.bz/2012/03/06/ajax-on-rails-ajaxified-create-and-destroy-actions-for-has_manybelongs_to-related-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

