git really is better than svn

Posted by Jason King 13 days 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 8 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 9 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 9 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 10 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 10 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 10 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 10 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 10 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 11 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.

SNAP!

Posted by Jason King over 2 years ago

You heard it here first (except for here, and hijacking attempts here and here) - the acronym of the moment is SNAP: Social Networking APplication. Be an early adopter! Stop writing it out longhand and join all the k00l kidz (actually I’ll settle for just having a blog article to point people to when they ask me what I mean when I use SNAP.

Deploying SVN tags and branches with Capistrano

Posted by Jason King over 2 years ago

Something which I came up against fairly early on in my Capistrano use was the problem of releasing from tags or branches in SVN. My normal development process for a large release is to tag the trunk, and then release from the tag. Then there are other times when I have a long-running branch that I want released as well. These posed some problems for Capistrano because the repository location was baked right into the deployment scripts.

…cont.