Cookie Session Store for Facebook Applications

Posted almost 7 years back at Darwinweb

I was recently recruited to build a facebook application on top of an existing Rails codebase running on edge. Having been on edge with my previous project for at least 6 months, I’ve gotten used to all the Rails 2.0 goodness.

One of my favorite features is the cookie session store which is a huge slam dunk for scalability and general maintainenance—that is to say, no maintenance.

Unfortunately facebook does not store cookies (as far as I can tell), and there is really no documentation of this to speak of out there on the web. If you are using the cookie session store, nothing blows up, you just don’t have a session. It’s pretty obvious when you think about it, but I spent a couple hours figuring out why my flash messages weren’t coming through. If this post saves one person 20 minutes, then it was time well spent.

Revisiting date localization for Ruby 1.8.6

Posted almost 7 years back at poocs.net - Home

Welcome to my yearly post about a revised version of a simple way to localize Ruby’s Time#strftime method (after my original post in ‘05 and the update in ‘06).

What’s changed?

In my original methodology, the arrays in the Date class containing the actual day and month names in clear text had to be replaced by strings wrapped in the infamous _() call of GetText in order to spit out their localized versions when requested from the modified Time#strftime call.

When Ruby 1.8.6 came along, it had its Date array constants frozen. While I agree it’s generally not a good idea to modify the contents of a constant (it’s a constant after all, mind you), the implementation I came up with 2 years ago worked fine up to and including today.

Since, also, most of the sites I’m working on require multiple languages (as opposed to, say, a single language set at application boot time), the contents of those Date arrays truly need to be modified at runtime and having those arrays frozen meant jumping through all sorts of hoops to address a supposedly simple issue.

What now?

Well, I had to come up with a way to actually execute the gettext functionality in the context of an object that has the current GetText locale bound to it. The most obvious object with that kind of property is ApplicationController.

But this still leaves us with the issue that we cannot modify the frozen Date constants and that everything we put into these constants is evaluated right away instead of at a point where we have the desired locale set.

What I came up with was a proxy object derived from the Array class that would basically just wrap the cleartext contents that are already in each of the Date arrays but not before they’re actually accessed/output.


    # lib/date_localization.rb
    class GetTextDateProxy < Array

      cattr_accessor :gettext_proxy

      def [](key)
        _(at(key))
      end

      def _(string)
        return string unless gettext_proxy
        gettext_proxy.instance_eval { gettext(string) }
      end

    end

As you can see, the proxy object is pretty simple after all. It just overwrites the default of Array#[] to look up the requested key and then wrap the output in _().

Since I couldn’t actually be bothered to include the whole of Ruby-GetText into my poor little proxy object, I then made room for it to hold a pointer to an instance of ApplicationController in a class attribute called gettext_proxy. The local underscore method of my proxy class then wraps around the actual gettext implementation available to the gettext proxy (read: ApplicationController), returning the string unchanged if there is no gettext proxy and if there is, run the string through the proxy’s gettext method.

Dealing with a state of not having a gettext proxy available is actually necessary in cases where there are calls to these arrays before ApplicationController gets to hook itself up to GetTextDateProxy.

But how does this actually hook into the Date class now? Let’s take a look:


    # lib/date_localization.rb
    class Date

      silence_warnings do
        %w(
          MONTHNAMES DAYNAMES ABBR_MONTHNAMES ABBR_DAYNAMES
        ).each do |array|
          class_eval %( #{array} = GetTextDateProxy.new(#{array}) )
        end
      end

    end

While this still looks a little tedious, it’s far less tedious than repeating the arrays’ contents simply wrapped in _() all over the place, like we had to do in previous incarnations of this methodology.

Basically, now every array is hooked up with their very own instance of GetTextDateProxy which then takes care of running the strings through gettext in the appropriate moments.

Wiring it all up

For the last part, we need to get ApplicationController to hook itself into GetTextDateProxy after having received the appropriate locale for the request it’s dealing with.

The best fit for this is the after_init_gettext hook provided by Ruby-GetText. Adding this code to ApplicationController will take care of the last required step.


    # app/controllers/application.rb
    after_init_gettext { GetTextDateProxy.gettext_proxy = self }    

Here you go, working (albeit hackish) localization for Ruby’s Time#strftime working up to and including the most recent version of Ruby, which is 1.8.6 as of this writing.

Enjoy.

Google Docs Basically Sucks

Posted almost 7 years back at Ryan Tomayko's Writings

The Google Docs editing UI is quite adequate, export to PDF / OpenOffice / Word is wonderful, and the collaboration stuff is strong but why cannot we produce modestly sane HTML or attach custom stylesheets?

Google Docs - Basically Sucks

Joho the Blog (in March 2007):

I've been using Google Docs to write documents that are collaborative. It’s a good first gen product, and I enjoy using it, but it would take a giant step forward if it let me apply a CSS style sheet to the docs I'm composing.

No shit. This is such an obvious idea that there must be something obviously wrong with it.

Joho the Blog continues…

This is such an obvious idea that there must be something obviously wrong with it.

Jinks!

Let me have a single URL box on the document and group settings page. Take whatever I put in there and stuff it in a <link rel='stylesheet' ...> in the head. At the very least, if I happen to plop something like that in via Edit HTML, let it through your sanitizer. And don’t even start on about <link> and <style> not being valid in the <body> – the generated HTML is such a complete mess that a minor offense like that is the least of your worries. Look at this (from a preview of a document):

<style>
BODY, P, DIV, TD {
   direction: inherit;
</style>

You have a better chance at validity from /dev/random.

I'm sure there’s all kinds of scripting vulnerabilities we’re worried about here but right now I'm just trying to Get Stuff Done and this is killing me.

What are some alternatives? I stopped reading TechCrunch but there has to be at least ten fairly mature browser based word processors out there by now. I like jottit’s URLs and overall simplicity but I also need the WYSIWG and I like being able to go out to .pdf, .doc, and .odt. But forget all that, is there anybody in this space that gives a shit about the HTML being generated? Let’s start there.

Want to know what Toronto's councillors are spending your money on ?

Posted almost 7 years back at work.rowanhick.com

Check this out. Council Expenses (robford.ca) Absolutely brilliant, and questionable all at the same time...

Mephisto gets a core team

Posted almost 7 years back at Beyond The Type - Home

Good news for Mephisto users. The core team has been decided and the ideas for the 1.0 release are being finalised.

Interestingly enough there may also be a push to switch over to using Git which is gaining a bit of traction in the Rails community. I’m an avid user of SVK and gave Git a try a while back but stopped short after hearing tales of woe with git-svn… I may revisit at some point.

Episode 76: scope_out

Posted almost 7 years back at Railscasts

The scope_out plugin will generate several helpful find methods for you automatically! It's the best way to move the find conditions into your model. Watch this episode for details.

Git Your Learn On

Posted almost 7 years back at zerosum dirt(nap) - Home

Any post about Git pretty much mandates the use of some lame pun in the title, and this blog entry is no exception. For those of you who are as-of-yet unfamiliar with it, Git is a distributed version control system created by Linus Torvalds. It’s been around and usable for about a year now, but I’d only been peripherally aware of it until recently.

In the past I’ve just used it to check out and occaisionally toy with the latest Rubinius sources but now that the Offtrac project is using it, it finally looks like I’m going to have to start familiarizing myself with it beyond installation and cloning a remote repository. If that sounds negative it isn’t meant to be; I enjoy being forced to learn new things every once in a while. Srsly.

[To be honest I’m still relatively happy with Subversion, but hey, when I started using Subversion I was still at least relatively happy with CVS too. No wait, scratch that, I hated CVS.]

Anyway, for those of you out there like me who are just getting acquainted with Git and particularly those who are stumbling over the implications of the distributed part of distributed version control, Carl Worth has written a useful getting started guide that you should definitely check out. Of course there’s the official user guide too.

In practice, normal usage really isn’t as different as it seems, and the concept of a distributed repository is a truly powerful one. Everyone has commit access to their own local branch, which means most operations are fast, and the centralized who-gets-commit-rights question becomes a total non-issue. That’s very very cool. Oh, and no .svn folders littered in every folder is another nicety. The jury’s still out for me as of right now, which is to say I’m not rushing to switch all my existing Subversion projects over just yet. But I have to say, I’m very intrigued so far.

718-123-2083

Posted almost 7 years back at zerosum dirt(nap) - Home

Someone rings my cell phone at 7AM this morning and asks “is this Nicholas”? I answer “yes”, because well, that’s my name. Then they hang up.

Apparently I’m not the only one this has happened to. Isn’t it good to know that there are communities for just about everything on teh Interwebs, including strange paranoia-inducing phone spam? But just who the fsck are these people anyway, and what in the world was the purpose of that? Sigh.

In unrelated but positive news, the Sox destroyed the Indians last night 11 to 2, winning the ALCS. Yes, I am a fair weather fan.

Scrivener, the best writing tool since sliced bread

Posted almost 7 years back at Cody Fauser

Have you ever wanted to write something, but felt so bogged down by the tools that you gave up? Even worse is if you don't even have the option of giving up. When I was writing RJS Templates for Rails using the O'Reilly Word template there were many moments when I thought that I may end it all. Thankfully, that didn't happen.

I have a profound hatred for Microsoft Word. I feel like its entire codebase exists solely to make my writing experience miserable. Capitalizing everything I need lowercase, formatting my paragraphs in ways that I don't want, just messing with my document to ruin my weekend. I'm sure it is possible to make Word do what I want, but I just don't feel like it is worth the effort. I don't want to waste my time figuring out how to make Word work for me, when what I want to do is really simple. I just want to write text. Is this a lot to ask for?

Thankfully, Tobias Lütke let me know about Scrivener. What can I say? Scrivener is fantastic. Scrivener not only gets out of my way when I'm writing, it actually has features that help with the process of writing. Scrivener helps in all the areas where it counts when it comes to writing. Organization, taking notes, keeping lists of reference material, storing research documents right in the project. Scrivener feels like a combination of a simple text editor with the power of an organizational tool like Omni Outliner built right in. You can create an outline in minutes, reorganize by dragging sections around, look at high level views of a section in a cork board view, and then turn off the entire UI when you're ready to get down to writing by entering the full screen typewriter mode.

There are many, many more killer features that I won't get into here. Do yourself a favour and get the demo. Better yet, just buy it. It only costs $34.99, which is less than you're going to spend next week at Starbucks anyway. You can get up to speed with all the features in less than an hour with the included tutorials.

ActiveMerchant PeepCode Screenshot

 

RailsConf Europe 2007 - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

Interviews with David Chelimsky, Dave Troy, Nick Sieger, and David Heinemeier Hansson.

Demeter's Revenge

Posted almost 7 years back at Luke Redpath - Home

For those who aren’t aware, the Law of Demeter – when applied to object-oriented programs – is a rule that determines which objects another object can send messages to based around the notion of an object knowing as little about the internal structure of the objects it interacts with.

It is commonly summarized as “Only talk to your immediate friends”. Please read the above Wikipedia article for more information and background.

This notion, when applied to Rails applications is equally valid however certain Rails practices seem to encourage demeter violations either through convention or API design and this can cause problems in all layers of your application. I am not the first to voice these concerns.

The issue of Demeter violations in views is a tricky one and not everybody agrees with Jay’s approach to solving violations in the view. Personally, I feel that when it comes to removing Demeter violations in the view, both approaches of adding simple wrapper/delegate methods or larger presenter-based solutions can be useful and choosing which approach to take depends largely on the complexity of the view in question.

Dealing with Demeter violations in Rails

However, my main concern with Rails when it comes to Demeter violations are those found in the controller and model. At Reevoo we try to write as much of our code using TDD or BDD as possible, making use of mocks and stubs to avoid unnecessary database calls (in both model and controller tests). It’s the issue of mocking and stubbing where Demeter violations can be particularly problematic as James and I found on a recent internal greenfield project.

Our new project was written using the Rails 2.0 pre-release and was written in a REST-ful fashion. When dealing with nested resources we would often have code that looked a little bit like this:

class WidgetsController < ApplicationController

  # POST /users/xxx/widgets
  def create
    # where @user was loaded in a before_filter
    @user.widgets.create(params[:widget])
    # and handle the result...
  end

end

We’re using the Rails convention of creating our associated widget object directly off of the User has_many association proxy. No apparent problem here but given that we wrote this test-first, look at the lengths we had to go through to make this work using appropriate mocking/stubbing:

class WidgetsControllerCreateActionTest < Test::Unit::TestCase
  def setup
    # usual rails controller test setup here
    @user = mock('user')
    User.stubs(:find).returns(@user)
  end

  def test_should_create_new_widget_for_parent_user_using_posted_widget_params
    widgets_proxy = mock('association proxy')
    @user.stubs(:widgets).returns(widgets_proxy)
    widgets_proxy.expects(:create).with(:name => 'my funky widget')
    post :create, :widget => {:name => 'my funky widget'}
  end

Because we are violating Demeter by getting a reference to the association proxy and then calling the create method on it all from within our controller, we’ve had to create a mock assocation proxy and stub the association proxy method on user to return it before we can set the expectation that we really care about (the :create call). It might not seem like a big deal, but we also have to make sure we stub @user.widgets to return something in every one of our tests for the create action otherwise we’ll find ourselves having problems with :create calls on a NilObject. Now multiply this issue by every single controller that contains a create action and things start to get very tedious.

The solution

The solution itself is not complicated and simply involves encapsulating the association proxy:

class User
  has_many :widgets

  def create_widget(*args)
    widgets.create(*args)
  end
end

Now our tests become much simpler and the intent clearer:

class WidgetsControllerCreateActionTest < Test::Unit::TestCase
  def setup
    # usual rails controller test setup here
    @user = mock('user')
    User.stubs(:find).returns(@user)
  end

  def test_should_create_new_widget_for_parent_user_using_posted_widget_params
    @user.expects(:create_widget).with(:name => 'my funky widget')
    post :create, :widget => {:name => 'my funky widget'}
  end

For our other tests, we only need to stub one method, the :create_widget method.

Again, whilst this doesn’t seem like a lot of effort, we now find ourselves having to write small delegate methods on all of our ActiveRecord models; and it’s not just create – we also find ourselves writing similar methods for all of our other association proxy methods (delete, update etc…). This too becomes very tedious, which is why my first thought was to try and automate the creation of these methods. This is where Demeter’s Revenge comes in.

“Demeter’s Revenge” is a simple extension to ActiveRecord, written as a Rails plugin that creates a collection of Demeter-friendly methods for your has_many and has_and_belongs_to_many associations. It doesn’t require any special configuration or installation – simply install the plugin as you would any other Rails plugin and your methods will become available to you. Here’s a quick overview of some of the methods you get access to and their standard Rails equivalent:

# given a User that has_many Widgets
user.build_widget(params) # => user.widgets.build(params)
user.create_widget(params) # => user.widgets.create(params)
user.number_of_widgets # => user.widgets.size (or .length)
user.has_widgets? # => user.widgets.any?
user.has_no_widgets? # => user.widgets.empty?
user.find_widgets(params) # => user.widgets.find(params)

For more examples, the plugin comes with a suit of RSpec examples. If you want to take a peek under the hood at the implementation, there is a full suite of specs. You can grab the plugin from my Subversion repository:

svn://lukeredpath.co.uk/var/svn/plugins/demeters_revenge/trunk

If you’re writing Rails apps and mocks and stubs have been causing you pain and/or Demeter violations make you cry, then hopefully this plugin will be of use to you. If you don’t care about Demeter violations and don’t use mock’s and stubs then its probably of less interest to you but I hope you give it a try anyway. If you have any feedback, feel free to drop me an e-mail (see the “correspondence” link in the site header bar) or leave a comment below.

Addendum

One of the things I’m not sure that I made very clear when I first wrote this entry was that this plugin is by no means a silver bullet to end all of your Demeter violation woes, nor are the problems experienced with mocking/stubbing the only reason to avoid violation Demeter violations which I could spend a whole article expounding on.

It just so happens that the pain felt when mocking/stubbing is symptomatic of Demeter violations in your code which should be enough to set alarm bells ringing. In the comments, Neil mentions that this is symptomatic of a problem with the mocking framework; whether or not you believe this to be true, any efforts to allow your mocks to work in such a way that would allow Demeter violating code to be easily mocked/stubbed, I fear that this would simply be a case of sweeping the problem under a rug and hoping nobody notices.

Creating a Mephisto Theme Using Liquid

Posted almost 7 years back at Mephisto - Home

Jon Baker wrote a great article on creating Mephisto themes. There’s also a nifty Liquid for Mephisto PDF cheatsheet by George that was released on the same day.

Finally, who posted as Dr Acula in the previous post? Totally awesome…

Episode 75: Complex Forms Part 3

Posted almost 7 years back at Railscasts

In this third and final episode on complex forms I will show you how to edit a project and multiple tasks all in one form. This includes removing and adding tasks dynamically as well. See the show notes for updated code.

Where's Nap?

Posted almost 7 years back at zerosum dirt(nap) - Home

Things have been kind of crazy lately, and blog updates have been few and far between. Sorry about that, it’s not that I’ve run out of things to say. Honest.

The truth of the matter is I’ve just been really busy with a couple client projects, and some other goodies that I’ll (hopefully) be writing about soon. And oh, yeah, I’m getting married this weekend too ;-).

So actually, the answer to the titular question is Martha’s Vineyard, where my lovely wife-to-be and I are renting a house for the week. It’s great to get away from (almost) everything for a little while.

Michael Koziarski - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

Rails core member Michael Koziarski talks about Rails 2.0, the new patch process, and working on the core team.
From RailsConf in Berlin.