A quick note on how to delete a tag from a remote git repository:
git push github :refs/tags/my_tag
A quick note on how to delete a tag from a remote git repository:
git push github :refs/tags/my_tag
Just a quick post to say that I will be slowly releasing the ruby gems used at SonicIQ over the next few weeks/months. The first (more to test the workflow of Jewler/Gemcutter/Github than anything), is IQ::HTML.
IQ::HTML is a super simple gem with a few helpers for creating html markup much like you’ll see in ActionPack, however this is it’s only task and is therefore useful when you don’t want the extra weight of ActionPack.
Next up will be IQ::Form which currently exists on Github but is undergoing significant changes so I would suggest waiting for the new release.
I have just had my sexy validations patch accepted into Rails. Much thanks to José Valim for helping me get this applied.
The reason for the name “sexy validations” is that it gives a much more concise way of defining validation and reusing custom validator classes. Much like what sexy migrations did for defining your database schema.
Simple example of using existing Rails validations, the “sexy” way:
class Film < ActiveRecord::Base validates :title, :presence => true, :uniqueness => true, :length => { :maximum => 100 } validates :budget, :presence => true, :length => { :within => 1..10000000 } end
The power of the “validates” method comes though, when using in conjunction with custom validators:
class IntenseFilmTitleValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors[attribute] << "must start with 'The'" unless value =~ /^The/ end end class SpendValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) spend = case options[:size] when :big then 100000000 when :small then 100000 end record.errors[attribute] << "must not exceed #{spend}" if value > spend end end class Film < ActiveRecord::Base validates :title, :presence => true, :intense_film_title => true validates :budget, :spend => { :size => :big } # using custom options end
All validations in Rails, along with other common model functionality have been extracted into ActiveModel, so you can also use validations and Validator classes without ActiveRecord e.g.
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors[attribute] << (options[:message] || "is not an email") unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i end end class Person include ActiveModel::Validations attr_accessor :name, :email validates :name, :presence => true, :length => { :maximum => 100 } validates :email, :presence => true, :email => true end
Have fun!
Wow, that’s a mouthful of a title.
Just run into an interesting bug in Webkit I believe. When using Colorbox on a link contained inside a div who’s overflow attribute was set to hidden, the div was being scrolled to the bottom when hitting the “close” link of the colorbox. This only seemed to happen in Webkit browsers.
The solution was to watch for a scroll event on the div in question and scroll back to 0:
$(document).ready(function() { var viewer = $('#viewer'); viewer.scroll(function() { viewer.scrollTop(0); }); });
Obviously, this is only a fix when you require your content to always be scrolled to the top, however this could serve as a starting point for other scenarios.
Update: This patch has been applied but this information is out of date, please see: this new post.
Having had a patch accepted in Rails, I now have the bug (not a bug… the bug for writing patches… anyway).
I have just added this patch to allow for “sexy-migration-esque” validations using the new ActiveModel. Below explains the gist of it:
class EmailValidator < ActiveRecord::Validator def validate field = options[:attr] record.errors[field] << "is not valid" unless record.send(field) =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i end end # Register the custom validator in an initializer file. ActiveModel::Validations.register_validator :email, EmailValidator class Person < ActiveModel::Base attr_accessor :name, :email validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 } validates :email, :presence => true, :email => true end
As with the previous patch I believe this adds even more flexibility which is what Rails 3 is all about. It also allows validators to be shared more easily.
Rails defaults can now also be overridden e.g.
class RequiredValidator < ActiveRecord::Validator def validate field = options[:attr] record.errors[field] << "Required" if record.send(field).blank? end end ActiveModel::Validations.register_validator :email, RequiredValidator
I would appreciate a +1 on the ticket from anyone who feels this should be in Rails 3.0.
I’m pleased to give you LucidGrid, a super useful bookmarklet for working with grid based layouts…
I have been working on a few grid based layouts of late and consistently find myself sitting with a calculator tapping out the various dimensions. I was surprised to find that there weren’t any simple bookmarklets for this so I wrote one.
LucidGrid allows you to supply a width, the number of columns you need and the gutter size and then overlays a grid on the current page. You may disable the grid by clicking the bookmarklet again or by clicking exit. If you choose to apply the grid, the preference dialog will minimise to the top right of the window.
Grid changes happen in realtime so it is easy to play with different settings.

Simply drag the link below to your bookmarks bar in your browser or click it to try it out first:
Enjoy… (currently tested with Safari 3.2.1 and Firefox 3.0.5).
I see unit testing as a way to test each possible snippet of functionality and route the code in question can take. With Ruby being such a dynamic language and allowing shortcuts to common problems, sometimes it can seem somewhat of a mystery, how to test these snippets of functionality.
Using Memoization as an example:
class MyClass def lazy_initialized_value @lazy_initialized_value ||= Expensive.request end end
There are actually 3 separate snippets of functionality that need testing here, however it is not immediately obvious from the example. Lets be slightly more verbose about what is actually happening:
class MyClass def lazy_initialized_value @lazy_initialized_value = Expensive.request unless @lazy_initialized_value @lazy_initialized_value end end
Now it is much easier to see the 3 steps the code should take:
* Store result of expensive request in instance variable
* Leave instance variable alone when it is already set
* Return the value of the instance variable
Now we have this information, our tests become (using Mocha to mock external methods):
class Expensive; end module Tests::MyClass # lazy_initialized_value # ---------------------- class LazyInitializedValueTest < Test::Unit::TestCase def test_should_respond assert_respond_to MyClass.new, :lazy_initialized_value end def test_should_store_result_of_expensive_request_in_instance_variable instance = MyClass.new Expensive.stubs(:request).with().returns('expensive value') instance.lazy_initialized_value assert_equal 'expensive value', instance.instance_variable_get('@lazy_initialized_value') end def test_should_return_value_of_instance_varable instance = MyClass.new instance.instance_variable_set '@lazy_initialized_value', 'the value' Expensive.stubs(:request) assert_equal 'the value', instance.lazy_initialized_value end def test_should_maintain_existing_instance_variable_value_when_already_set instance = MyClass.new instance.instance_variable_set '@lazy_initialized_value', 'existing value' Expensive.stubs(:request) instance.lazy_initialized_value assert_equal 'existing value', instance.instance_variable_get('@lazy_initialized_value') end end end
Now we have these tests in place, we can go back and refractor the code ’til our heart’s content using all the tricks in the book but by simplifying the problem in the first place, it gives us a solid test suite and the confidence to make changes without breaking functionality.
If you were solving this problem test-first then you wouldn’t (but more likely, shouldn’t) have written the first example until re-factoring stage anyway, however when these shortcuts become engrained in your brain, it’s all too easy to forget what they are _actually_ doing.
So there we go, simplify the initial implementation, get a solid test suite in order, _then_ re-factor.
I was happily mocking away with Mocha, then I passed a stub to a case statement at which point I was a little flummoxed.
The Ruby documentation clearly states that the ‘when’ in a ‘case’ statement uses the ‘===’ method for comparing the subject so I couldn’t work out why something like the following wasn’t working:
# Code class A; end def foo(instance) case instance when A : 'an A instance' else 'not an A instance' end end # Test a = stub_everything a.stubs(:===).with(A).returns(true) assert_equal 'an A instance', foo(a)
So I had a little play around in irb and found the following:
class A; end a = A.new a === A #=> false A === a #=> true
This revealed that I was actually stubbing the wrong side of the operator, I changed this to the following and voila!
# Code class A; end def foo(instance) case instance when A : 'an A instance' else 'not an A instance' end end # Test a = stub_everything A.stubs(:===).with(a).returns(true) assert_equal 'an A instance', foo(a)
Looks obvious now but certainly wasn’t at the time!
There is loads of documentation and posts on Git out there so this is more of a note to self as I keep forgetting the steps to setting up a remote repository and doing an initial ‘push’.
So, firstly setup the remote repository:
ssh git@example.com mkdir my_project.git cd my_project.git git init --bare git-update-server-info # If planning to serve via HTTP exit
On local machine:
cd my_project git init git add * git commit -m "My initial commit message" git remote add origin git@example.com:my_project.git git push origin master
Done!
Team members can now clone and track the remote repository using the following:
git clone git@example.com:my_project.git cd my_project git-track origin
Note: the ‘git-track’ command is a bash function we use to save manually editing the .git/config file (add the following to your ~/.bash_profile file as outlined by darkliquid):
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function git-track {
CURRENT_BRANCH=$(parse_git_branch)
git-config branch.$CURRENT_BRANCH.remote $1
git-config branch.$CURRENT_BRANCH.merge refs/heads/$CURRENT_BRANCH
}
h4. Bonus
To have your terminal prompt display what branch you are currently on in green, add the following to your ~/.bash_profile:
function parse_git_branch_and_add_brackets {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\ \[\1\]/'
}
PS1="\h:\W \u\[\033[0;32m\]\$(parse_git_branch_and_add_brackets) \[\033[0m\]\$ "