Josh Susser - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

Newly knighted Rails blogger Josh Susser muses on database relationships and reliable apps.

Common Rails Performance Problems

Posted almost 7 years back at RailsExpress.blog

InfoQ has published an article on common Rails performance problems (written by me). You can head over to read all about it.

David Black - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

The RubyCentral co-founder talks about his new book, Ruby for Rails.

Update to Unobtrusive Javascript Plugin

Posted almost 7 years back at Luke Redpath - Home

Update 15 Feb 2009: The UJS plugin for Rails is no longer actively maintained but you can find the the source on github.

Some small changes and one major bug fix have been checked into Subversion today:

  • The controller action that serves up event-selector.js, eliminating the need to manually copy it to your public/javascripts folder, was looking for the js file in the wrong place, stopping the whole plugin from working. If you've already discovered this, please run an update.
  • There is now an unobtrusive version of the link_to_remote function - this also dynamically appends a return false to the onclick event to ensure it works in Safari (see this blog post)
  • The rules are now assigned using an addLoadEvent function instead of window.onload - this is more of a quick fix and will be improved in the future (I plan to use Prototype's onReady extension) but in the meantime this makes sure it doesn't mess up any other onload events you might have.
  • The rules are re-applied automatically on completion of any AJAX request

Please post any bugs to the Agile Evolved Open Source Trac.

Introducing Unobtrusive Javascript for Rails

Posted almost 7 years back at Luke Redpath - Home

Update 15 Feb 2009: The UJS plugin for Rails is no longer actively maintained but you can find the the source on github.

Rails makes a lot of things easier for a developer. One of those things is AJAX. The built-in Javascript and AJAX helpers, such as form_remote_tag and link_to_remote, make developing AJAX apps a breeze. But if there has every been one major bone of contention with these helpers, it's the markup they produce. Developers have been well aware of the need to separate content from presentation with CSS for a while now - less prevalent is the recognition of the benefits in separating behaviour from content.

Update 21/08/2006: The latest version of this plugin is 0.3 - please see this post and the official UJS website for more information.

Rails makes a lot of things easier for a developer. One of those things is AJAX. The built-in Javascript and AJAX helpers, such as form_remote_tag and link_to_remote, make developing AJAX apps a breeze. But if there has every been one major bone of contention with these helpers, it's the markup they produce. Developers have been well aware of the need to separate content from presentation with CSS for a while now - less prevalent is the recognition of the benefits in separating behaviour from content.

I'm not going to cover the ins and outs of why you should separate behaviour from content here, but or those unfamiliar with the reasons and benefits, Peter-Paul Koch of QuirksMode published a great article in 2004 highlighting the benefits of separating behaviour from content. More recently, Dan Webb from Vivabit published an article about the problem with Rails AJAX helpers.

As Dan points out in his article, the subject has been mentioned on several occasions on the RubyOnRails mailing list but has often been shot down for a multitude of reasons ranging from "its not worth it" to "it would be too awkward". Invitations to submit patches were made but nothing came about.

So I'd like to present to you something I've been working on here at Agile Evolved - Unobtrusive Javascript for Rails. The plugin makes use of a Javascript library called event:Selectors by Justin Palmer at EncyteMedia. Similar to Ben Nolan's behaviour.js library but making full use of Prototype, it allows you to use CSS selectors to attach Javascript events to your page. This plugin allows you to make use of the event:Selectors library, but in Ruby, directly from your controller or view and have the resulting behaviour rules dynamically generated at runtime in an external javascript file. Let me demonstrate:

First of all, you'll need to grab the plugin from the Subversion repository. Please note - the plugin is in its early stages at the moment and is likely to be updated quite a bit over the coming weeks - I do not recommend using this in a production site just yet. In the meantime, if you want to have a play I recommend using svn:externals to make sure you keep your copy of the plugin up-to-date.

$ ./script/plugin install -x http://source.ujs4rails.com/current/unobtrusive_javascript

Next, you'll need to load in the Prototype javascript and the Unobtrusive Javascript scripts. Somewhere between your layout's head tags, add the following:

<%= javascript_include_tag :defaults %>
<%= unobtrusive_javascript_files %>

You can now attach events to elements in your page from either your controller or your view, using the register_js_behaviour() function. The function takes two parameters; the first is the CSS selector and event (for more details see the event:Selectors documentation) to attach your behaviour to and the second is a string of Javascript that you want to execute. Here's a small example:

<% register_js_behaviour "#my_funky_link:click", "alert('Hello World')" %&gt;

Of course, writing out large strings of javascript could become cumbersome. The first solution is use the built-in Rails helpers to generate your Javascript strings. For instance, if we want to highlight a div when we hover over it with the mouse, you could do the following:

<% register_js_behaviour "#my_funky_div:mouseover",
        visual_effect(:highlight, "my_other_div", :duration =&gt; 0.5) %>

Now, if you load up a page with one of the above calls and View Source, you might expect to see a whole load of generated Javascript. Except you won't - thats because the unobtrusive_javascript plugin makes use of a special controller and view to dynamically generate your behaviour rules at runtime, which are then linked to using a normal script tag. That means you can attach as many behaviours to your page as you like, from anywhere in your view or controller, without clogging up your rendered HTML with Javascript.

Next, there is the issue of graceful degradation. The two primary candidates for graceful degradation are the link_to_remote and form_remote_tag helpers - links and forms both have natural fallbacks - the HREF and ACTION respectively, and by using some unobtrusive Javascript we can make sure those fallbacks are used when somebody has Javascript disabled.

This initial release contains an updated version of the form_remote_tag helper - by default it does exactly the same thing as the built-in Rails helper but making it use unobtrusive Javascript is a case of one small addition to your code:

<%= form_remote_tag :url => { :action => 'foo' }, :unobtrusive => true %

Because the event:Selector library depends on an HTML ID to attach an event, your forms will need an ID but worry not - another modification to the form_remote_tag helper will mean that if you do not specify your own HTML ID, one will be automatically generated for you.

Finally, some of you may be aware that Dan Webb, who I mentioned earlier in this article, has been working on his own unobtrusive javascript plugin. I have been in touch with Dan and he preferred the simpler syntax that my plugin uses. That said, he's plugin contains some very cool stuff and we've agreed to merge the best of both of our plugins together over the coming weeks, including the ability to supply the register_\javascript_behaviour() function with a block which will let you write the Javascript functionality you want to attach using Dan's RJS-style JavascriptProxy classes.

Please do download the plugin and have a play around. You can report any bugs on the Agile Evolved Open Source Software website and any opinions and ideas are welcomed.

Unobtrusive Javascript in Rails...what if?

Posted almost 7 years back at Luke Redpath - Home

Update 15 Feb 2009: The UJS plugin for Rails is no longer actively maintained but you can find the the source on github.

What if...you could produce accessible, unobtrusive javascript, using Rails built-in javascript/prototype helpers, with just one extra line of code in your layout, a plugin, and one small enhancement to the helpers? Something like this:

<% form_remote_tag :controller => 'foo', :action => 'bar', :unobtrusive => true %>

Which produces:

<form id="form_foo_bar" action="/foo/bar" method="post">

But which still acts as an ajax form? You would simply handle the response for ajax and non ajax requests using Rails' responds_to function.

In addition, what if you could attach javascript functionality to your page elements in a Behaviour-like fashion, but using pure Ruby, anywhere in your view, but loaded from an external Javascript file?

Sorry to tease. Stay tuned, we have something very cool to show off in the next day or two.

http://opensource.agileevolved.com

Sebastian Delmont - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

The lead developer of StreetEasy talks about bridging web 1.0 and web 2.0 for the New York real estate market.

Simpler Piggy Backing

Posted almost 7 years back at RailsExpress.blog

A while ago I posted an article about the performance improvements obtainable by piggy backing. Although the speedups where substantial, I received some negative comments about exposing too much SQL to the programmer.

Exposure to the underlying SQL is not such a big problem for me, that it would deter me from applying the technique. But I found that I had a lot of repetition in my code, which I didn't like.

After ignoring the problem for a while, I decided it was about time to deliver a better solution than manually coding selects and joins.

I wrote a small extension to ActiveRecord, which makes piggy backing extremely simple.

Instead of coding joins and selects manually, you can now declare the piggy backed attributes from a has_one or belongs_to association in your model classes like so:

class Article
  belongs_to :user
  piggy_back :user_name_and_birthday, :user, :name, :birthday
end

This will generate all necessary select and join statements, which can then be added to a query rather elegantly:

article = Article.find :first,
            :piggy => :user_name_and_birthday,
            :conditions => "articles.title LIKE '%piggy%'"

would retrieve the first article which contains 'piggy' in its title attribute, along with the birthday and name attributes of the corresponding User object, storing them in the attributes hash of the AR instance.

But this is not all! After declaring the piggy backed attributes, you will also get reader methods which retrieve the attribute for you from the AR instance, and, should a type cast be required, convert the value to the correct type.

The piggy backed attributes are accessed like this:

article.user_name        ==> a string
article.user_birthday    ==> a date

Additionally, should you forget to piggy back a query,

article = Article.find :first,
            :conditions => "articles.title LIKE '%piggy%'"

methods user_name and birthday will silently use the user association to retrieve the values for you. This make is possible to use user_name and user_birthday regardless of whether your original query was piggy backed or not.

I've ensured that all of this works with pagination. In fact, using the extension is slightly faster than coding the select and joins manually (1%-3%).

You can download the code here. I haven't turned it into a plugin yet, so you need to add a require 'piggy_back' to your environment.rb.

Enjoy!

Update:

  • I failed to mention that piggy backing also works with finds on associations, so
article.comments.find(:all, :piggy => :user_name)

works as expected.

  • Upon popular demand it's now possible to use a more verbose syntax. You can write
class Article
  belongs_to :user
  piggy_back :user_name_and_birthday,
      :from => :user, :attributes => [:name, :birthday]
end

for the example above.

  • Piggy backing is now available as a plugin using the URL svn://railsexpress.de/plugins/piggy_back/trunk

Tom Copeland - Ruby on Rails Podcast

Posted about 7 years back at Ruby on Rails Podcast

Take a tour of RubyForge with sysadmin Tom Copeland!

Ruby en Rails 2006

Posted about 7 years back at RailsExpress.blog

Next week, there’s a Rails conference in the Netherlands, Ruby en Rails 2006, were I will present my wisdom about Rails performance tuning. If you live nearby, and haven’t registered yet, now’s your last chance!

I’m sure it will prove to be a very interesting event. I’m especially looking forward to hear about a Ruby.net implementation project, presented by Wilco Bauwer.

And, of course I anticipate the after conference event, where we should have plenty of time to relax and dream up new ideas to save the world from joyless programming!

Update: I must say this was a very well organized event at a beautyful location, were I’ve met very nice people. It was a real pleasure to be there.

My slides are now available for download.

Obie Fernandez - Ruby on Rails Podcast

Posted about 7 years back at Ruby on Rails Podcast

Obie Fernandez of ThoughtWorks gives a peek into how Ruby is making inroads into the enterprise.

Planet Argon - Ruby on Rails Podcast

Posted about 7 years back at Ruby on Rails Podcast

Planet Argonites Robby Russell and Jeremy Voorhis team up on Rails deployment, refactoring, databases, and National Album Recording Month.

Eyelook: Rails photo gallery

Posted about 7 years back at

Eyelook is a photo gallery I created over a weekend when I was home sick. It is amazing how productive rails can make you because within 8 hours I had the code in place and had set it up on my personal web server.

Very little of that time was spent coding – most of it was spent working on re-arranging the xhtml+css or figuring out how to go about Loading Binary Data into Rails Fixtures.

Every eyelook application has a set of users who have a list of albums with pictures. The image data is stored in the database and cached on the filesystem on demand. This way a backup of the database backs up the complete system.

An example of users page that lists galleries is

You can select one of these galleries and it will bring up a list of images such as

From there you can either download the original or can view a larger lightbox style image

The admin section is not as sexy but it is functional.

You can grab the source from subversion via the following command. Read the README.txt for installation instructions.

svn co http://www.realityforge.org/svn/code/eyelook/trunk eyelook

Tim Bray - Ruby on Rails Podcast

Posted about 7 years back at Ruby on Rails Podcast

Tim Bray, co-inventor of XML, talks about the appeal of Ruby as a dynamic language and where Java might have a place in the future of Rails. Also features Obie Fernandez and Dave Astels.

Loading Binary Data into Rails Fixtures

Posted about 7 years back at

Loading image data into fixtures was a chore until recently as I had been using separate rake tasks to do the job. The following code demonstrates how easy it is to load binary data such as images into the fixtures via standard mechanisms. It loads some image data from within the $RAILS_ROOT/test/fixtures/ directory and puts it in database.

<%
def fixture_data(name)
  render_binary("#{RAILS_ROOT}/test/fixtures/#{name}")
end

def render_binary(filename)
  data = File.open(filename,'rb').read
  "!binary | #{[data].pack('m').gsub(/\n/,"\n    ")}\n"
end
%>
picture_data_1:
  id: 1
  picture_id: 1
  content_type: 'image/jpg'
  data: <%= fixture_data("picture_data_1.jpg") %>
picture_data_2:
  id: 2
  picture_id: 2
  content_type: 'image/gif'
  data: <%= fixture_data("picture_data_2.gif") %>

If you do not use two spaces as your indent then you will need to alter the line in render_binary(filename) that replaces newline so that every newline is replaced with two indents.

Easy peasy!

Update on 16th April 2006

It turns out that it was not as easy peasy under postgres as the driver did not know it had to escape the data as binary as fixtures don’t actually load the column type. The simplest hack around it is to add in the following bit of code somewhere that just patches the driver if a 0 is in the data. This may not always work but it works with my test data so that is good enough for me at the moment.

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
  def quote(value, column = nil)
    if (value.kind_of?(String) && column && column.type == :binary) || (value.kind_of?(String) && value.include?(0))
      "'#{escape_bytea(value)}'"
    else
      super
    end
  end
end