Sample Rails code

This is for someone else.  I’m including some comments for explanation, but the target reader(s) will understand.  Sorry, folks, it was more readable than email.

from Entries controller – gets appropriate entries, plus start and end date.

   1:  class EntriesController < ApplicationController
   2:    before_filter :login_required
   3:    
   4:    def index
   5:      
   6:      @week_num = 0
   7:      if !params[:week].blank?
   8:        @week_num = params[:week].to_i
   9:      end
  10:      
  11:      @entries, @begin_date, @end_date = current_user.entries.find_for_week @week_num
  12:      
  13:      respond_to do |format|
  14:        format.html
  15:        format.js {render :layout => false, :partial => "list", :locals => { :entries => @entries, :begin_date => @begin_date, :end_date => @end_date }}
  16:      end
  17:    end
  18:   
  19:  ...
  20:   
  21:  end

 

Entry model method – does the dirty work of getting the records. returns records plus dates.

   1:  class Entry < ActiveRecord::Base
   2:    belongs_to :user
   3:    
   4:    def self.find_for_week(num)
   5:      # finds weeks in reverse order. 0 is current week. 1 is last week, 2 is 2 weeks ago. etc.
   6:      #assume monday is first day of week
   7:      t_now = Time.now - (7*24*60*60 * num)
   8:      t_wday = t_now.wday==0 ? 6 : t_now.wday-1
   9:      t_mon_begin = t_now - (t_wday)*24*60*60 - t_now.hour*60*60 - t_now.min*60 - t_now.sec
  10:      t_sun_end = t_mon_begin + 7*24*60*60 - 1
  11:      entries = find_all_by_on_date(t_mon_begin..t_sun_end, :order => 'on_date DESC') # ..finds all within range.
  12:      return entries, t_mon_begin, t_sun_end
  13:    end
  14:    
  15:  end

 

index.html.erb – renders the header, new link, and partial with list. update div is for the ajax call.

   1:   
   2:  <h2>Time Entries</h2>
   3:  <p><%= link_to 'new', new_entry_path, :class=>'applink', :id => 'new' %></p>
   4:   
   5:  <div id="update">
   6:  <%= render :partial => "list", :locals => { :entries => @entries } %>
   7:  </div>

 

_list.html.erb – renders links for ajax navigation, and list of records.

   1:  <% if @week_num > 0 %>
   2:  <%= link_to 'Next Week', '/entries?week=' + (@week_num.to_i - 1).to_s, :class => "get"%>
   3:  <% end %>
   4:  <%= link_to 'Prev Week', '/entries?week=' + (@week_num.to_i + 1).to_s, :class => "get"%>
   5:  <input type='hidden' value='<%= @week_num.to_i + 1 %>' id='weeknumber' />
   6:   
   7:  <% if flash[:notice] or flash[:message] or flash[:error] %>
   8:          <div id="flash" class="flash_html">
   9:            <%= flash[:notice] unless flash[:notice].blank?%>
  10:            <%= flash[:error] unless flash[:error].blank?%>
  11:            <%= flash[:message] unless flash[:message].blank?%>
  12:          </div>
  13:  <% end %>
  14:  <br/>
  15:   
  16:  <p> For week starting on: <%= @begin_date.strftime('%a, %b %d %Y') %></p>
  17:  <table cellpadding='3px' cellspacing='3px' border='0px'>
  18:  <tr>
  19:    <th width="30px"></th>
  20:    <th width="100px">Action</th>
  21:    <th width="100px">Date</th>
  22:    <th width="60px">Hours</th>
  23:    <th width="150px">Project Code</th>
  24:    <th width="200px">Description</th>
  25:  </tr>
  26:  <%= render :partial => "entry_row", :collection => @entries %>
  27:  </table>

 

_entry_row.html.erb – renders the actual row data

   1:  <tr>
   2:    <td><%= entry_row_counter+1 %></td>
   3:    <td><%= link_to 'edit', edit_entry_path(entry_row) %> | <%= link_to("delete", {:action => "destroy", :id => entry_row}, :confirm => "Are you sure you want to delete this entry?", :method => :delete) %></td>
   4:    <td><%=h entry_row.on_date.strftime('%b %d %Y') %></td>
   5:    <td><%=h entry_row.hours %></td>
   6:    <td><%=h entry_row.code %></td>
   7:    <td><%=h entry_row.description %></td>
   8:  </tr>

 

from application.js – jquery javascript used for ajax call, updating html, and setting click method on certain links

   1:  jQuery.fn.getWithAjax = function() {
   2:    this.unbind('click', false);
   3:    this.click(function() {
   4:      //$.get($(this).attr("href"), $(this).serialize(), null, "script");
   5:      $.ajax({
   6:        url: $(this).attr("href"), 
   7:        type: 'get', 
   8:        dataType: 'html',
   9:        success: function(msg){
  10:          $('#update').html(msg);
  11:          ajaxLinks();
  12:          }
  13:      });
  14:      return false;
  15:    })
  16:    return this;
  17:  };
  18:   
  19:  //This will "ajaxify" the links
  20:  function ajaxLinks(){
  21:      $('.ajaxForm').submitWithAjax();
  22:      $('a.get').getWithAjax();
  23:      $('a.post').postWithAjax();
  24:      $('a.put').putWithAjax();
  25:      $('a.delete').deleteWithAjax();
  26:  }
  27:   
  28:  $(document).ready(function() {
  29:    //default click event for all links
  30:    $('#applink').unbind('click', false);
  31:    $('#applink').click(function() {
  32:      self.location = $(this).attr("href");
  33:      return false;
  34:    })
  35:   
  36:    $.ajaxSettings.accepts.html = $.ajaxSettings.accepts.script;
  37:   
  38:    $(document).ajaxSend(function(event, request, settings) {
  39:         if (typeof(window.AUTH_TOKEN) == "undefined") return;
  40:         // <acronym title="Internet Explorer 6">IE6</acronym> fix for http://dev.jquery.com/ticket/3155
  41:         if (settings.type == 'GET' || settings.type == 'get') return;
  42:         settings.data = settings.data || "";
  43:         settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(window.AUTH_TOKEN);
  44:       });
  45:       
  46:    $(document).ajaxSend(function(event, request, settings) {
  47:      if ( settings.type == 'post' ) {
  48:          settings.data = (settings.data ? settings.data + "&" : "")
  49:              + "authenticity_token=" + encodeURIComponent( AUTH_TOKEN );
  50:      }
  51:    });
  52:    ajaxLinks();
  53:    
  54:    $(document).bind('keyup', 'Ctrl+l', function(){ self.location = "/login"; } );
  55:    $(document).bind('keyup', 'Ctrl+r', function(){ self.location = "/register"; } );
  56:    $(document).bind('keyup', 'Ctrl+e', function(){ self.location = "/entries"; } );
  57:    $(document).bind('keyup', 'Ctrl+o', function(){ self.location = "/logout"; } );
  58:    $(document).bind('keyup', 'Ctrl+n', function(){ 
  59:      //alert($('a#new').length);
  60:      if($('a#new').length) {
  61:        //$('a.new').trigger('click');
  62:        $('a#new').click();
  63:      }
  64:    } );
  65:  });

 

 

screenshot – looks like this because a good css and design haven’t been added.  this is after navigating back a couple weeks; notice the url shows it wasn’t just navigating pages.

Screen shot 2009-12-16 at 10.53.27 PM

 
December 16, 2009 23:05 by josh
E-mail | Permalink
blog comments powered by Disqus


about josh

another programmer blogging about his misadventures in writing code.

Contact

contact us for website & software consulting

Decide

decide on pragmatic solutions

Develop

develop your product together

Succeed

achieve your goals with our services