Ruby 1.8 and 1.9 living in harmony

Posted by Jason King 17 days ago

I’m running on OSX, and using MacPorts for all my un-Apple needs. So, no, getting Ruby 1.9 installed was not complex at all, the suffix is the default in MacPorts, so I just ended up with a ruby1.9 executable.

The kicker comes because Rails, and all its little generator friends, do one of two things. Either they are just hardcoded to use #!/usr/bin/env ruby or they set that line to whatever version of Ruby you happen to be using when you install/generate/make them the first time, which will be either what I’ve just written or #!/usr/bin/env ruby1.9 or (like rails) an actual hard coded path to your MacPorts ruby executable.

Ok, not really a big problem there, until you want to test your application, generator, plugin, gem, whatever against the other ruby on your system. What do you do? Go through and make sure you change all the relevant shebangs? Works fine until you miss one. You’re really testing your sed fu, not your Ruby fu.

And then what happens when, like me, you’re just so used to typing irb or ri that you’re constantly tripping over the “Oh, yeah, that’s over in the 1.9 stuff.” problem?

Well, then you know it’s time to roll out your bash fu. Ewk!

I rolled up these bash functions to switch my MacPorts installation from 1.8 to 1.9 by taking all the binaries that are part of the ruby macports install and moving them to suffixed files, and then symlinking the bare names to either 1.8 or 1.9 (which IMHO should always be how languages are installed).

So, dependencies? It depends on you having macports - it uses that to get the list of files that have been added to the relevant bin directory. You could replace that in the for loop with something else to give you those filenames.

That’s it.

Hmm, or it would be it if I said: run r18 to switch to Ruby 1.8 and run r19 to switch to Ruby 1.9. Also - warning - this runs sudo, so understand what you’re running before typing in your password.

Comments: 2 (view/add your own) Tags: 18, 19, macports, osx, ruby

jquery in Rails3

Posted by Jason King 29 days ago

There are two things you want to sort out in Rails3 to get jquery humming along really nicely.

Firstly is the UJS. Rails3 has done great things in replacing all the inline JS with UJS and nice semantic XHTML - but, of course, they ship with the Prototype version of this UJS file.

You’ll want to just overwrite the public/javascripts/rails.js file in your project with the jquery version from github.

So the next step would be to add the javascript_include_tag to all your layouts, and if you’re a jquery fan then you’re probably used to something like this:

javascript_include_tag 'jquery', 'jquery-ui', 'rails', 'application'

At best, if you have only one layout, that’s ugly. When you begin to get more than one layout, you’re un-DRY, or you’re writing your own helper to wrap that up. It just gets uglier. Especially when compared to the Prototype equivalent:

javascript_include_tag :defaults

How do we get this logical grouping of JS files?

Well, I might just be the last one at the party here, but I couldn’t find anything online, or anything obvious in the help, for how to DRY this up. A quick dig in the source revealed the answer though. Somewhere in your init files (in Rails3 I have this in config/application.rb - but this will work in previous versions of Rails too) you can register what’s called an expansion, like so:

ActionView::Helpers::AssetTagHelper.register_javascript_expansion \
  :jquery => %w/jquery jquery-ui rails application/

So then in your layouts you can use that expansion like so:

javascript_include_tag :jquery

Much nicer, and very simple to update in a central config location, should you wish.

git really is better than svn

Posted by Jason King about 1 month ago

For many months when git (or really when github) first arrived on the scene I heard nothing else from all the fanboys than how great git was, how crap svn was, and that everyone who was anyone was using git now. That sort of zealous response to new software or services always gives me pause.

Inevitably, I’d ask one of the fanboys why they recommended git over svn, and usually they would come up with one of two standard “reasons”

…cont.

Comments: 0 (view/add your own) Tags: git, scm, svn

Simpler test output with turn

Posted by Jason King 9 months ago

This is a small thing, but sometimes those small things can really make a huge difference. This is one of those.

As your suite of tests grow, especially in those large applications, you often end up with an error output that looks something like this:

..........F..............F.....E....FFF...F..........

And then following that is a huge list of error details. Scrolling through that is a pain, and even with redgreen active your visual cues are at a minimum when looking through that output.

Thankfully this also annoyed Tim Pease who came up with a very pleasant alternative called turn. You can install it as a gem, and then just add:

require 'turn'

Into your test helper and you’ll see much simpler and comprehensible output from your test output.

A few more things in the Rails console

Posted by Jason King 10 months ago

Almost immediately after posting my last post on the Rails console a few more things came to mind. It has taken me this long to blog again :)

Let’s pick up from where we left off in the previous post with…

…cont.

When REST doesn't fit

Posted by Jason King 10 months ago

So, those of you that know me know that I’m no REST zealot. I think there are many times when it’s better to use a non-REST controller. Simplicity of URLs, succinctness of controller, etc..

One example that I’ve just come across is a questionnaire which doesn’t really map to REST. For a start I never want to expose this controller via an API, the process flow also doesn’t follow REST at all, sure I want a new questionnaire completed, but that’s it. I don’t want to be able to show, edit/update or delete.

…cont.

Column sorting with good_sort

Posted by Jason King 11 months ago

I spent a little time this week pulling sorting out of a project of mine as a gem. I’m really happy with where I got to with it.

What this is is something that lets you very easily add column sorting to your data views so that visitors can click on the column headings to re-present the data sorted by that heading.

…cont.

A couple of things in the Rails console

Posted by Jason King 11 months ago

So for anyone who doesn’t know, the script/console in Rails runs up an irb process behind the scenes. It also loads Rails into the context, and a few other bits - but mainly it’s an irb session.

I’ve just been getting a couple of “Oh wow, I didn’t know that.” responses when I mention these things in #rubyonrails, so I thought I’d just post this here.

Thing 1: the underscore method

The return from every command that you enter into irb is available in the underscore method _. So, if you’re like me, you often run a command and then think that you should have assigned it to some variable, or pretty-printed it or something.

…cont.

Comments: 5 (view/add your own) Tags: console, irb

Case insensitive SQLIte

Posted by Jason King 11 months ago

One of the things that quickly tripped me up in using SQLite in Rails was that there was no way to make a column case insensitive.

Most human textual comparisons are case insensitive, we think that “dog” and “doG” and “DOG” all denote the same thing. If we have a uniqueness constraint on a column, then we want it to protect us from having three separate entries for those three strings. Also, when we’re searching for “dOg” we want it to match any one of the three strings.

Every database has its own way of doing these sorts of things - SQLite uses one of the more sensible methods: it allows you to specify that any column you like should be case insensitive (and then any index on that column will automatically be case insensitive too).

So, you can write:

CREATE TABLE foo ( bar varchar(255) COLLATE NOCASE );

And you’ll get a case insensitive column ‘bar’. This is so often what you want, more often than not, so I wrote a quick gem that does this by default for all your migrations.

This is a kludgy kludge!

What would be nice would be to add a new option to the migration methods so that any given column could be marked with something like: :case => false Unfortunately, the Rails code for all that is not very DRY and stuffed with metaprogramming - so it’s not easy to retrofit a gem to make that happen. So my gem just makes it happen for every string or text field.

Mostly this will be what you want, but every so often case sensitivity is something that is desirable - so beware :)

Dot Versions

Posted by Jason King 11 months ago

Ok, so there are chunks of code I write again and again, and this is one of them:

class Version 
  include Comparable
  def initialize(_v); @v = _v.split('.').map(&:to_i); end
  def <=>(_v); @v <=> _v.split('.').map(&:to_i); end
  def to_s; @v.join('.'); end
end

I was going to reformat it, so that the methods are all newlined properly, but actually - you should have to put up with looking at it like I look at it.

So, what does this do? Well, check this irb out:

irb(main):001:0> '3.6.8' > '3.6.4'
=> true
irb(main):002:0> '3.6.8' > '3.6.10'
=> true
irb(main):003:0> # Ack!  Should be false

We get a true because they’re strings, so they’re being compared alphabetically. Rescue us wonderful Version class:

irb(main):004:0*   class Version 
irb(main):005:1>     include Comparable
irb(main):006:1>     def initialize(_v); @v = _v.split('.').map(&:to_i); end
irb(main):007:1>     def <=>(_v); @v <=> _v.split('.').map(&:to_i); end
irb(main):008:1>     def to_s; @v.join('.'); end
irb(main):009:1>   end
=> nil
irb(main):010:0> v = Version.new('3.6.8')
=> #<Version:0x547e0 @v=[3, 6, 8]>
irb(main):011:0> v > '3.6.4'
=> true
irb(main):012:0> v > '3.6.10'
=> false

Yay. That’s it, you can get it here.

SQLite > MySQL or Transactional DDLs ftw

Posted by Jason King 11 months ago

Let’s get into it. SQLite kicks arse! It wipes the floor with MySQL and comes back for more. The only time not to use SQLite is when your app goes viral and you have six or seven figure hits per day at which point you should go to Postgres.

Where does MySQL fit in? Nowhere!

What are DDLs and what does it mean to have Transactional DDLs?

Why does SQLite rule, and why would I consider it for production?

What does “lite” really mean?

Read on…

…cont.

Scribbish for simplelog

Posted by Jason King 12 months ago

New look and feel - I quickly ported Scribbish over to simplelog because I was sick of the dark. Next I want to find out whether I can easily get syntax highlighting onto my webhost.

Stay tuned for posts about transactional DDLs coming soon for SQLite in Rails 2.3.

Also a really neat tool for getting started on a new gem.

Also a really nice tool for viewing your test output and making it a bit clearer (especially good for those huge test suites.

Back soon.

Oh, I just stuck it up on GitHub, here.

named_scope - start using it!

Posted by Jason King about 1 year ago

As I pointed out here on the WWR Forums when you have a set of static conditions, even if you only use them once, then you should consider using a named_scope to encapsulate those conditions in your model.

So instead of having this in your controller:

app/controller/foos_controller.rb

def inactive
  @foos = Foo.all(:conditions => "active is null")
end

You would shift that concept off into your model by using a named scope. So you’d have this instead:

app/models/foo.rb

named_scope :inactive, :conditions => "active is null"

app/controller/foos_controller.rb

def inactive
  @foos = Foo.inactive
end

Note that what’s returned from inactive is a proper ActiveRecord collection, so you can call all your AR records on it, eg:

@foos = Foo.inactive.find_all_by_bar(params[:bar])

This is a great way to push the business logic off into your model and refer to it by name (not code) from your controller.

guerrilla_rotate released on github

Posted by Jason King about 1 year ago

A/B testing, split testing, side-by-side testing, call it what you like but for those interested in improving the performance of their marketing it’s crucial to test your copy, headlines, imagery and visual arrangement.

I’ve just packaed up guerrilla_rotate, an internal tool that I’ve been using for a while, and stuck it up on my new best friend: github

It’s best to use this in combination with Rubaidh::GoogleAnalytics in which case it’ll just do what you expect for your stats. If you don’t use that, then you’re on your own with how to track the stats, manual analytics of some sort, or who knows - old school, unique image tags in each view.

Have fun.

inline_attachment all fixed now

Posted by Jason King about 1 year ago

I’ve just rewritten inline_attachment to have more features, with less code, and be more reliable (ie. not as likely to break with a Rails version bump).

The coolest new feature is full support for the ActionMailer auto-multipart feature, so mostly you won’t need to write any complex MIME part crap in your model. No code is always good :)

Quickly

app/models/notifier.rb

class Notifier < ActionMailer::Base
  def signup
    recipients %q{"Testing IA" <testing@handle.it>}
    from       %q{"Mr Tester" <tester@handle.it>}
    subject "Here's a funky test"
  end
end

# Oh yeah baby!  Read it and weep!  So how's this work?  Well, you'll need
# your templates named properly - see the `Multipart email` section of the
# ActionMailer::Base docs.

signup.text.plain.erb

Your username is: <%= @username %>

signup.text.html.erb

<html>
  <head>
    <title>Signup Notification</title>
  </head>
  <body>
    <%= image_tag "logo.png" %>
    <p>Your username is: <%=h @username %>
  </body>
</html>

Obviously you also need that logo.png in your public/images directory.

…cont.

Remote script/console

Posted by Jason King over 2 years ago

Someone on #rubyonrails asked a question the other day, whether there was a capistrano task to open a script/console over ssh on the remote server. Such a brilliant idea that I asked him to fill me in if he found it - and he did, here

Instead of having to open an ssh session, and cd to the right dir, and fire up script/console you can just use the cap task from the comfort of your project dir on your local machine:

cap remote:console

…cont.

Another Day Another Release - Acts Pretty Plugin

Posted by Jason King over 2 years ago

I’ve ditched this because to_param is just such a simple solution. Google it and read, it’s so simple.

Simplify Your Adsense With Rails

Posted by Jason King over 2 years ago

When we incorporated Google Adsense into Freedraw we just couldn’t find a simple to use plugin that would insert the ads we needed into our layouts.

How the plugin works is simple, you define how the ad should look within your config/googlead_sense.yml file (a sample one is provided with the plugin). You’ll want to change at least the adclient setting otherwise I’ll get all your ad revenue.

Actually, don’t change that setting! :)

Then just add it into your views or layouts, like so:

<%= google_ad %>

This is a bit different to how the old one worked, you used to have to define all those settings in each controller that you wanted to use the helper in.

This is simpler, and you still have some control over the format in your view, like so:

<%= google_ad(:skyscraper) %>

To install the plugin:

script/plugin install git://github.com/JasonKing/google_ad_sense.git

You can see more here

Challenge Authentication Released

Posted by Jason King over 2 years ago

For those you who are unfamiliar with our new approach to user authentication click here to read all about it.

We’ve finally completed a plugin for those who want to try out this new password-less method of user authentication.

The plugin is based off of the well known Restful Authentication plugin so it should be fairly straight forward to use and integrate with your own systems.


I’m rewriting and rethinking this plugin (really a generator), and how it can best be integrated into really useful things like IM and maybe twitter.

Just-in-Time Branching in SVN

Posted by Jason King over 2 years ago

Something which I’ve really fallen in love with recently is something I’ve named Just-in-Time Branching. It allows my coding brain to just code without having to think about whether something is so large that it has to be branched, and I don’t need to think about when the next release is going to go out, or what the other developers and doing and whether what I’m doing will interfere with their code.

…cont.