Dynamic date exclusions w/ JQuery Datepicker, Rails & Gon

A question came up the other day when I was showing a colleague the reservation page for the restaurant app I’ve recently written (http://alianosbatavia.com): If the restaurant is closed, can you dynamically exclude dates from the JQuery date picker? The answer was yes – but I hadn’t found a nice way to do it. The way it previously was configured looked something like this (coffee script):

  $("#reservation_date").datepicker(
    minDate: "-0d",
    maxDate: "+1Y",
    showOtherMonths: true,
    selectOtherMonths: true,
    beforeShowDay: (date)->
      closedDates = [[12,25],[1,1],[8,22]]
      for closedDate in closedDates
        if(closedDate[1] == date.getDate() && (closedDate[0]-1) == (date.getMonth()))
          return [false]
      return [true]
  )

Fast forward to yesterday – I was watching Railscast episode #324 during my morning commute. It’s about passing data to javascript from Rails apps. There are a few ways to do that using HTML data tags, etc, (I’ll let you watch the episode) but the last suggestion involved using a gem called Gon. Gon essentially creates store of values at the window level in javascript and pumps it full of data from variables in your controllers in your Rails app (again, more details in the episode).

Using Gon to exclude dates from the JQuery date picker? Super easy.

You need to include gon in the head tag of the page on which it will be used. I added mine to my applications layout:

In application.html.erb:

<head>
  <title><%=h yield(:title) %></title>
  <%= include_gon %>
  <%= stylesheet_link_tag "application" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>

That will add the gon storage to every page. Next, add some data to the gon storage:

In my controller methods (or in a filter):

gon.exceptions = closed_dates

And now, from my JQuery date picker config:

In my assets/reservation.js.coffee:

  $("#reservation_date").datepicker(
    minDate: "-0d",
    maxDate: "+1Y",
    showOtherMonths: true,
    selectOtherMonths: true,
    beforeShowDay: (date)->
      closedDates = gon.exceptions
      for closedDate in closedDates
        if(closedDate[1] == date.getDate() && (closedDate[0]-1) == (date.getMonth()))
          return [false]
      return [true]
  )

That’s it! Be sure to check out the Railscast and the Gon github page for more details.

Simple caching in Rails 3.1

Parting ways with http://alianosbatavia.com has been a lot harder than I thought. Every time I think I’m going to hang it up, I think of something new to add to it.  Recently, I wanted to use simple caching to load blocks of reservations at start up, then refresh those blocks after each successful update of blocks from the admin UI.  Here we’ll talk about reading to and writing from the cache in Rails 3.1.

Writing to the cache

In config/initializers/load_reservations.rb:

require File.dirname(__FILE__) + '/../../lib/reservations_loader.rb'
Rails.cache.write(:reservation_blocks, ReservationsLoader.build_reservations_map)

Reading from the cache
In app/models/reservation.rb:

blocks = Rails.cache.read(:reservation_blocks)

Pretty easy.  I have an observer on ReservationBlocks that refreshes the cache the same way it initially loads it on startup.  This gives me a fast and easy way to display only reservations that are available for the currently selected date on the reservations screen without having to query the database every time a reservation time is requested.

Kind-of-a book review: Design Patterns in Ruby

It has been many years since I have read this much information on Design Patterns, and in those days the language the book was based on was Java. While the concepts still apply, Design Patterns in Ruby does a great job of walking through the classic patterns. First, the way we learned them – with abstractions and interfaces – followed by iterations toward the ‘Ruby’ way.

Moving between languages and development styles effectively can be difficult. It’s not just syntax, either. At the basic level, most languages function the same way. Conditionals are conditionals and loops are loops. Personally, getting into the “culture” of the language is the important part. In my opinion, culture is not just defined as the language, but also, language feature usage, development styles, etc. Switching projects and being productive on the first day is possible, but really hitting your stride takes a week or two. After the first week or two, you’re remembering the syntax better, you’re remembering and using language features appropriately, etc.

That is the thing I think I’ll like about this book more than anything else. This book does a good job of spelling out the cultural differences between a language like Java and a language like Ruby; how to get your brain from thinking in Java to thinking in Ruby. The original GoF book on patterns for Java was a set of recipes that solve common problems – in this case, we get the same, along with the transition between the two, as well as patterns that can be uniquely addressed using Ruby.

The one line summary of this book: “Language features and the dynamic nature of Ruby make common design patterns easier to implement clearly with fewer lines of code.”

A quick refresher with a book like this before my next Ruby project will be in order.

Size doesn’t matter (or work, apparently)

Here’s a quick one.

Recently when doing some Rails work, I was using FormHelper to add a text area to an erb and couldn’t seem to get the size param to work. The Rails API docs clearly mention the use of the ‘:size’ param or the ‘:rows’ and ‘:columns’ params being acceptable.

For what it’s worth, neither seem to render in Firefox 3/4 or Safari. If you’re having the same problem, add a style to your text area to control the size, and you should be in business…

     <%=form_builder.text_area(:attribute, {:class=>"aSizedTextArea"})%>

In your css file:

.aSizedTextArea {
    overflow-y: scroll;
    height: 100px;
}

Like learning English from an auctioneer…

As we all know, skill retention has a lot to do with level of immersion and length of stay – the deeper you are into a particular technology and the length of time that you’re at that depth usually are directly related to how long you can remember a given technology, language, or practice.

My experience with Ruby and Rails reflects this. I’ve been in and out of two projects in my free time while working on other projects during the day. My approach to picking up Rails was similar to how I picked up Groovy and Grails – get a book and read it . In my case it was the classic Advanced Web Development With Rails. Coming from a java background, the learning curve for Groovy was easy. I only had to learn Grails. For Ruby and Rails, diving right into Rails was ok, but I glossed over a lot of the Ruby syntax and shortcuts, assuming I would pick them up later. With Ruby having a steeper learning curve for me, and not being deeply immersed in these projects for long periods of time, my personal velocity suffered. It was like learning English from an auctioneer – too often going back to find syntax examples of things I knew I wanted to do, but couldn’t remember exactly how…

A few weeks back a co-worker sent a link to our team about Ruby Koans (http://rubykoans.com/). While I’m not a huge fan of the ‘path to enlightenment’/’Zen b.s., they serve as a fast and hands-on way to learn the language (and it’s shortcuts), and serve as a quick reference point for use later. In short, I’m a big fan, and if you’re interested in learning Ruby and making it stick, I recommend working through them. The easiest way to get started is at github: (https://github.com/edgecase/ruby_koans).

ruby_koans = awesome (or is it ruby_koans == awesome?) Check the koans!

It makes sense now!

I just got through a few days of using jdpace’s PDFKit gem for rails. It is a very straightforward PDF generation tool for Rails which uses the wkhtmltopdf tool to generate PDF documents from HTML and CSS3. After watching the great-as-usual Railscast on the topic, there were just a couple of missing pieces that I had to put together from the PDFKit github wiki and few other sources. Here’s what the problem was:

I wanted to respond_to requests as either PDF or HTML, but only for certain actions. I also wanted to send formatting instructions to wkhtmltopdf. Here’s what filled in the blanks for me:

In environment.rb (this is a Rails 2.3.8 project):

require 'pdfkit' #above the run block
#code below belongs within the run block
config.middleware.use PDFKit::Middleware
  Mime::Type.register 'application/pdf', :pdf

In my controller I want to make the default layout nil (so my reports either use no layout, or use their own), and I want to respond to requests with pdf of the source page…

layout nil
def my_report
respond_to do |format|
      format.html
      format.pdf {
        html = render_to_string(:action => "my_report")
       kit = PDFKit.new(html, :page_size => 'Letter', :margin_bottom=>".25", :margin_top=>".25", :margin_left=>".25", :margin_right=>".25")
        kit.stylesheets << "#{Rails.root}/public/stylesheets/my_stylesheet.css"
        send_data(kit.to_pdf, :filename => "generate_a_file_name", :type => 'application/pdf')
        return
      }
    end
end


That is all. You can also change the disposition option for the generated pdf in the respond_to block to have the pdf render in the browser rather than download. There are many references to using the extended help feature of wkhtmltopdf to find more formatting options to pass to the generator. Be sure to use the correct names! Some names in the help file will not be the same as their equivalent labels in your app.

Just call me Casey Jones

I’ve recently found myself involved in some RoR work. It took a bit to take my java blinders off, but since they’ve been off, the work has been great. With past Grails experience in mind, here are a few first observations after a couple of weeks of being a Rails dev under my belt.

I like migrations
I used to think I liked the “declare everything in the model” style of defining models in grails, but since then I’ve come to appreciate having to write migrations for the (dare I say?) discipline they force upon the author. Writing those migrations makes me think carefully about how the model change I’m trying to make impacts what’s already in the database.

Plugin/gem maturity
The community is strong – there are far more useful plugins/gems available for RoR apps than there are for Grails apps. You get just a few key choices in a Grails app. With an RoR app, and this sometimes can be cause for concern, there are many plugins to choose from – authorization and authentication gems are a good example. There are basically two choices in Grails – Spring Security and JSecurity. There are many choices for RoR apps, and further, they can be mixed and matched with the authorization and authentication components being separate.

Railscasts
So useful. I’d like to have the option of choosing a celebrity voice-over for them, though. Homer Simpson and/or Snoop Dogg would be my choices. http://railscasts.com/

The learning curve
Groovy & Grails has a definite advantage in being easier to pick up for someone with a java background. I think this is also a downfall of groovy/grails, because it is so easy to fall back to java instead of learning a new (or more efficient) way to solve a problem (ie with a new language and framework a la RoR).

The enterprise and it’s architects
Code that runs on hardware they’ve already got, that leverages existing resources (people and hardware), and is at least somewhat familiar to them is appealing. RoR is not this.

C to tha I
If I can’t roll a build and have Chuck Norris give me the thumbs up afterwards, I am somehow not satisfied. Autotest, rspec, and growl can get me by in the meantime.

… I just wrote a rake task. I’ll write about that later.