Freelancing Gods 2014

God
23 Oct 2007

Request for Caching Questions

The monthly Melbourne Ruby meeting is happening this Thursday, and I’ll be presenting about Rails’ caching (of the page, action and fragment varieties). Just wondering if any of the few readers of this blog had either suggestions for content, or, especially, questions they’d like to see addressed in such a talk?

Slides will, of course, be posted after the meeting.

22 Oct 2007

Web Directions South 2007

It’s a bit delayed, but I just wanted to write a little report (read: link to everyone and reminisce) on my trip to Sydney for Web Directions South 2007. So, in chronological order…

The Conference

I hadn’t been to Web Directions before – but I had made it to one of the preceding Web Essentials conferences, which had been great. This time around though, far better – for a variety of reasons. One difference was finding it really helps knowing a few people who are also attending – that strengthens the whole social side of the conference.

Some of the speakers, though, were brilliant. Andy Clarke ran an interesting session about the design of comics, John Allsop’s passion for the web was evident in his entertaining talk, and Scott Berkun’s presentation about the myths of innovation was fantastic as well.

The highlight, though (and I think most people who were there agree with this) was Mark Pesce’s Mob Rules. Grab the podcast of his talk and listen to it (any parts that interrupt Mark are clips from Robot Chicken). Mark’s an amazing speaker, and his content was thought-provoking. A fantastic way to end the conference.

The After-Party

After that, it was to the Shelbourne Hotel to drink, chat and party into the early hours of the morning. While I didn’t really contribute to drinking through the Microsoft-provided tab, I did get to meet several interesting people. One of which was John Allsop, who was one of the organisers of Web Directions. I’d like to say we discussed politics, social issues and the web – but to be honest, it was more John ranting and me listening (not that that’s a bad thing, John’s always entertaining).

John also pseudo-introduced me to Michael Koukoullis, which, joined by Nick Pellow, lead to further opinionated discussion about politics. There’s a blog post prompted by the topics we covered (and one of John’s blog posts) sitting in my head – hopefully I’ll get it down into some textual form at some point soon.

Web Shack at the Nerf Palace

The following day was filled with code – well, that was the plan. Most of us were pretty drained from the previous night, and I also got distracted by the AFL Grand Final.

I did manage to get pagination working in Thinking Sphinx though, and technorati support for this blog. I also got to experience the the tasty delights of Bourke St Bakery (particularly their raspberry and dark chocolate muffins) – so it definitely wasn’t a waste of time. Was also great to catch up properly with some of the roro crew.

WebJam

And then onto the fantastic WebJam – which involved more drinks, partying, presentations of funky web stuff, and meeting people. Once that eventually wound up, I was introduced to what is apparently a Sydney institution, Harry’s Cafe de Wheels – their Tiger Pie tasted far better than what I was expecting.

Which pretty much brings us to the end of my Sydney adventures (for this journey north, anyway). Massive thanks to all involved in the events, each was awesome.

21 Oct 2007

Link: James on Software: Introducing resource_controller: Focus on what makes your controller special.

21 Oct 2007

Link: rubymatt's mailtrap-0.2.1 Documentation

A mock SMTP server for use in development environments.

18 Oct 2007

Link: ar-backup - Google Code

"Active Record backup is a Rails plugin which lets you backup your database schema and content in a schema.rb file and fixtures."

09 Oct 2007

Link: Hivelogic: Enkoder Rails Plugin

Plugin that encodes email links (and other content)

03 Oct 2007

A Thoughtful Sphinx

In one of the projects I’ve been working on lately, I’ve needed to implement a decent search – and so I looked at both Ferret and Sphinx. I ended up choosing the latter, although I’m not sure why – perhaps just to be different (most people I spoke to are using ferret), or perhaps because the setup seemed easier.

The next step was to pick a Sphinx plugin to work with. Ultrasphinx seemed to have a good set of features (particularly pagination), and supported fields from associations within indexes – something critical for what we were doing.

Unfortunately, grabbing fields from associations wasn’t that easy – and the SQL generated for the Sphinx configuration file was overly complex. I could (and did) change the config file manually, but that makes half the usefulness of the plugin worthless.

So, since I had some spare time, I wrote my own plugin. Much like Rails, it favours convention over configuration – perhaps a little too much so at this point, but I do plan to make it more flexible at some point. Installation is the same as any other plugin:

script/plugin install
  http://rails-oceania.googlecode.com/svn/patallan/thinking_sphinx

An example of defining indexes (within a model class):

define_index do |index|
  index.includes.email
  index.includes(:first_name, :last_name).as.name
  index.includes.tags.key.as.tags
  index.includes.articles.content.as.article_content
end

To index the data, just use the thinkingsphinx:index rake task (aliased to ts:in) – which will also generate the configuration file on the fly. My goal is to make changing the configuration file manually unnecessary – making the index task build the configuration file helps enforce this.

And to search:

# Searching particular fields
User.search(:conditions => {:name => "Pat"})
# Or searching all fields
User.search("Pat")
# Pagination is built in
User.search("Pat", :page => (params[:page] || 1))

Paginated results can also be used by the will_paginate helper from the plugin of the same name. Current documentation can be found on this site.

I managed to use ActiveRecord’s join and associations code, which kept my plugin reasonably lean. For interactions with Sphinx’s searchd daemon, I did look at Dmytro Shteflyuk’s Ruby Sphinx Client API, but the non-ruby-like syntax irritated me, so again, I coded my own – heavily influenced by the original though (ie: he did all the hard work, not me).

There’s no support for some way to update the index pseudo-incrementally (something that is a limitation of Sphinx). If I don’t feel like the incremental updating works well enough, then I may switch to Ferret – which might lead to a Thinking Ferret plugin, perhaps. We’ll just have to wait and see.

Nov 14th 2007 – Update: I’ve just released the internal Sphinx client as its own library – Riddle.

01 Oct 2007

Conditional Caching

Whenever I’ve described caching in Rails to anyone who isn’t familiar with it, I have made clear the limitations of each method:

  • Page caching is only useful when the output is exactly the same for every visitor, and you don’t need to confirm user authentication
  • Action caching allows you to run filters for every request – thus can be used to check if users are authenticated – but the rendered output has the same limitations as page caching
  • Fragment caching, while flexible, is definitely slower than the other two options.

Obviously, it’s best to use the fastest caching possible that fits your pages. That’s rarely page caching for the sites I code. Even action caching hasn’t been viable too often. Or so I thought.

I used to use fragment caching in most of my views – generally with extra parameters to indicate user role, so it would store different versions of the fragment for each role (ie: admin user, normal user, no user). This worked reasonably well, but often I was wrapping an entire view in a <% cache do %> block – almost action caching!

In the site I was coding at the time, ausdwcon.org, I realised the best time to cache would be when no user was logged in – as that would cover the majority of requests. So, to simplify: what I wanted was caching only when a certain condition was true.

Getting methods coded for conditional caching at a fragment level was a piece of cake. At the action caching level? Well, that was trickier, but with some help from the RORO crew I got it working, and into a plugin. You can find the code in the RORO svn repository and the documentation on this site. To install:

script/plugin install
  http://rails-oceania.googlecode.com/svn/patallan/conditional_caching

One brief example so you know what to expect:

# a controller
caches_action :index, :if => :no_user?

# application.rb
def no_user?
  session[:user_id].empty?
end

Obviously the :if parameter is the key – it can be a symbol pointer to an instance method on the controller, or it can be a Proc which is evaluated in the scope of the controller.

Now, the no-user condition is the only example I can think of where my plugin is useful – if you think of others, please let me know. Keep reading though, because I’ve got another helpful hint or two to share.

I mentioned above my usual method of using fragment caching – liberal use of extra parameters. It’s actually possible to do this with action caching too – which I only found out recently, so I’m assuming there are other people out there who aren’t aware of it either.

It’s not quite as easy as the equivalent fragment caching code, as you’re using both class and object level methods, but here’s an example:

# a controller
caches_action :index, :show, :cache_path => cache_params

# application.rb
def self.cache_params
  @cache_params ||= Proc.new { |controller|
    controller.params.merge(:role => controller.current_role)
  }
end

This has actually made me cut back on usage of my plugin – because most of my pages don’t have user-specific content.

Oh, and one more thing – to cut down on user-specific content in my views, I’ve been mapping my users controller as both a normal resource and a singleton resource. This means instead of a “Your Profile” link being /users/34, it’s just /user. Makes the controller code a little tricky, and the named routes get confused, but nothing a few clever helper methods can’t fix.

29 Aug 2007

Link: smartbomb - Hornsby

Scenario-focused spec'ing, instead of fixtures

09 Aug 2007

Link: PdfWriter and RailsPdf - RailsOnWave Ruby on Rails web 2.0 Ajax

Jim - is this something new?

03 Aug 2007

Link: SpinBits // Services

30 Jul 2007

Link: Client HTTP Caching in Rails - igvita.com

28 Jul 2007

Link: AssetPackager – JavaScript and CSS Asset Compression for Production Rails Apps

19 Jul 2007

Link: Making Rails Go Vroom

16 Jul 2007

Link: tumblemantim: normalise those URLs

01 Jul 2007

Link: less everything Paypal on Rails...ActiveMerchant tips

24 Jun 2007

Link: Obie Fernandez : Weblog : Ruby on Rails and More...

23 Jun 2007

Link: god - process and task monitoring done right

01 Jun 2007

Link: subLog : HTML / CSS to PDF using Ruby on Rails

25 May 2007

Link: Rails Log Visualizer

RssSubscribe to the RSS feed

About Freelancing Gods

Freelancing Gods is written by , who works on the web as a web developer in Melbourne, Australia, specialising in Ruby on Rails.

In case you're wondering what the likely content here will be about (besides code), keep in mind that Pat is passionate about the internet, music, politics, comedy, bringing people together, and making a difference. And pancakes.

His ego isn't as bad as you may think. Honest.

Here's more than you ever wanted to know.

Ruby on Rails Projects

Other Sites

Creative Commons Logo All original content on this site is available through a Creative Commons by-nc-sa licence.