Douglas F Shearer

Latest


Clearing a File Input Field Using JQuery

While working on some file uploads today, I was in need to a way to clear a file input field if a user changed their mind after selecting a file. I came up with the following simple solution.

In my example I place a ‘clear’ link next to the field, but a modified method could be called from anywhere.

HTML

Wrap the field you intend to clear in a span, with a descriptive ID so we can find it.

We’ll also want our ‘clear’ link to be descriptively IDed.


<span="myfileinput"><input type="file" name="myfile" /></span>
<a href="" id="clearmyfile">clear</a>

JavaScript

Now in our JavaScript (JQuery) we want to add a click event to our clear link which will clear the file input field.


$('#clearmyfile').click(function(){
  var fieldSpan = $('#myfileinput');
  fieldSpan.html(fieldSpan.html());
});

Explanation

Since we can’t write to the value of a file input field due to security concerns, instead we overwrite the contents of the span, with the contents of the span (itself), thus creating a new file input DOM object which doesn’t have a value set.

A crude but working example can be found in this Gist.

 

Simple Rails Config

There are a lot of Rails config options around, but despite this, I thought I’d share mine.

My design goals for this were:

  1. Once the configuration was loaded, it would be stored in memory for the next time it was required.
  2. Nice usage syntax, like config.authentication.password rather than the oft-used config[:authentication_password].
  3. Zero dependencies outside what is already included in Rails.

config/app.yml


  # Rails Config.
  # Copyrighted(c) Douglas F Shearer 2009
  # Licensed under The MIT License.
  site:
    url: http://example.com

  authentication:
    username: bob@example.com
    password: myhackproofpassword

  flickr:
    api_key: d3c3576398a4876c920553b714bc177f
    username: flickrusername

  # Akismet.
  wordpress:
    api_key: 876c920553b7

config/initializers/config.rb


  # Rails Config Loader.
  # Copyrighted(c) Douglas F Shearer 2009
  # Licensed under The MIT License.
  module Config

    class ConfigStore

      # Takes a hash as an argument.
      # If this hash contains other hashes, these too will turned into
      # ConfigStore objects.
      def initialize(contents)
        @contents = contents

        @contents.each do |k, v|
          if v.is_a?(Hash)
            @contents[k] = self.class.new(v)
          end
        end

      end

      def method_missing(sym, *args)    
        @contents[sym.to_s] || super
      end

    end

    def config
      @@config ||= ConfigStore.new(YAML.load_file("#{RAILS_ROOT}/config/app.yml"))
    end
  end

  include Config

Usage

With both these files in place, we can now call the config from anywhere in our app:


  >> config.authentication.username
  => "bob@example.com"
  >> config.authentication.password
  => "myhackproofpassword"

I’ll probably add overrides for environment specific configuration in the future, but this covers most of my needs for now.

 

Easy_Install Leopard bug: No Eggs Found

Today I came across Zed Shaw latest awesome project, Lamson, an Python mail server that isn’t stuck in the past. The Register has a pretty good rundown on it if you want to know more.

So anyway, on installing it, one of it’s dependences, the jinja2 templating engine, exposed a bug in easy_install that seems to be quite prevelant on OS X 10.5 Leopard. The error message will be something like No eggs found in /foo/bar/etc (setup script problem?).

The solution is to upgrade to the latest version of easy_install as so:

sudo easy_install http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c9-py2.5.egg

Best to check the project page to see if a newer version has be released.

Credits: A similar older fix by Sean Lynch with a non-working patched upgrade.

 

Flic.kr - Flickr Short URLs Explained

Flic.kr links recently began appearing on Twitter and around the web, so I did a little bit of digging. Twitter has brought about a wild storm of URl shortening services, and some issues surrounding them. James Duncan Davidson has a good summing up of these, and some of the solutions.

One of these solutions is to use a link tag on a page to give an alternative short URL. Flickr has started to support this, as so…

On a photo page, say http://www.flickr.com/photos/douglasfshearer/3447346323/, we find in the source:


<link rev="canonical" type="text/html" href="http://flic.kr/p/6fCxXz" >

Twitter clients can now take a pasted Flickr link, and go look up this short url on the Flickr page, without making use of a third party service such as tr.im. Good stuff.

This also works for user accounts, as an example, mine would be http://flic.kr/douglasfshearer.

Tools

The short photo URL is the photo ID converted to Base58, so you need to turn one into the other.

The item that really brought this to my attention was Fraser Speirs Base58Encode Objective-C class, ideal for those of you making Twitter clients.

I’ve released a RubyGem for this, Base58, and a CLI script that takes a flickr URL and gives you the short version.

 

Acts_As_indexed v0.5.0 Released

My Acts_as_indexed plugin has been updated to version 0.5.0.

New in this version is:

  • Ruby 1.9 and Rails 2.3 compatibility.
  • Index location can now be set. Provides Heroku compatibility.
  • Better errors on bad options.
  • ActiveRecord order argument overrides ranking returned by find_by_index.
  • Various test environment improvements
  • Various Bugfixes

Get it on Github or view the RDoc.

 

Testing Custom Rails Validations with Shoulda

In this post, I’ll show how to write custom validations for Rails’ models, and how to test them with Shoulda, the ‘Makes tests easy on the fingers and the eyes’ testing plugin.

Rails’ ActiveRecord validations are great when you want to make sure attributes are the way you want them. But what about the use-cases where you need to write a custom one?

Creating the Validation

The validation we’ll write is called validates_positive_or_zero, which will return an error if a relevant integer attribute is negative.

Create the file RAILS_ROOT/lib/validations.rb with the following contents:


def validates_positive_or_zero(*attr_names)

  1. Set the default error message.
    configuration = { :message => “Cannot be negative” }
  1. Set a custom error message if there is one.
    configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
  1. Check none of the object’s attributes are negative.
    validates_each attr_names do |obj, atr, val| obj.errors.add(atr, configuration[:message]) if val < 0 end
    end

Note: This particular validation is complementary to validates_numericality_of, you’ll get some odd failures if you don’t use it.

We need to require this file before we can use the new validation in our model:


class Badger < ActiveRecord::Base
  require 'validations'

validates_numericality_of :age, :height, :weight validates_positive_or_zero :age, :height validates_positive_or_zero :weight, :message => ‘no-one is that light’

end

The first validates_positive_or_zero validates two attributes at once, whereas the second validates only one attribute with a custom error message.

Testing the Validation

I feel I should give a little introduction to Shoulda, it’s one of those tools that leaves me wondering how I ever managed before. Despite the popularity of RSpec within the Ruby community, I’m not a fan, it’s just too verbose, which I find gets in the way (it doesn’t render views though, which makes functional testing a lot easier, this feature for standard Rails tests please!). Shoulda is the answer for those of us who want standard Rails tests, but with them being neater and tidier. I encourage you to check it out more fully, but for this example, I’ll stay on-subject.

For our custom validation we could test it in the regular fashion with a test_foo method, or we could write a custom method that we could use again and again without re-writing the same code. The latter is the approach we are going to take here, with the method being in the style of the other shoulda validation tests.

First up, install the Shoulda plugin:

./script/plugin install git://github.com/thoughtbot/shoulda.git

Next, create the file RAILS_ROOT/test/shoulda_macros/validations.rb with the following contents:


class Test::Unit::TestCase

def self.should_only_allow_positive_or_zero_values_for(*attributes) configuration = { :message => “Cannot be negative” } configuration.update(attributes.pop) if attributes.last.is_a?(Hash) klass = model_class attributes.each do |attribute| attribute = attribute.to_sym should “only allow positive or zero values for #{attribute}” do assert_bad_value(klass, attribute, -1, configuration[:message]) end end end private
  1. Taken from the shoulda private methods
    def model_class
    self.name.gsub(/Test$/, ’’).constantize
    end

end

Now we set up our tests in RAILS_ROOT/test/units/badger_test.rb:


require 'test_helper'

class BadgerTest < Test::Unit::TestCase
  
  # This method is provided by Shoulda.
  should_only_allow_numeric_values_for :age, :height, :weight
  
  should_only_allow_positive_or_zero_values_for :age, :height 
  should_only_allow_positive_or_zero_values_for :weight, :message => 'no-one is that light'
  
end

And we’re done! I hope this was useful for you.

 

GitHub Bookmarklet Updated

I’ve added support for Github’s repository search and making use of their new search to Github Bookmarklet.

Get it

Drag this to your bookmarks bar: Github Search.

Repository Search

As for user and code-search, but use the r: prefix. You can also use any of the GitHub macros as defined in the blog post linked from above.

r: will_paginate

Docs etc

 

Rails Plugin: Acts As Follower

Followers are the new friends. Apps such as Twitter and Github have effectively enabled virtual stalking within their apps. So how can you do this easily without wasting time with your own join tables? Acts_As_Follower to the rescue!

Install

./script/plugin install git://github.com/tcocca/acts_as_follower.git

Usage

A service like Twitter would have a user model, which would be both a follower and followable…


  class User < ActiveRecord::Base
    acts_as_follower
    acts_as_followable
  end
  
  # In the console...
  user1.follow(user2)
  
  # Get the users following user2
  user2.followers # => # Array containing user1
  
  # Get the users user1 is following
  user1.following # => Array containing user2
  
  # Check following
  user1.following?(user2) # => true
  user2.following?(user1) # => false
  
  # Stop following
  user1.stop_following(user2)
  

Acts_As_Follower allows heterogeneous follow relationships too, so a user could follow repositories and users, say, in an application like Github.

This plugin saved me a lot of time during the start-up of a recent project, and it hopefully should do the same for you. For more usage examples, see the README.

 

GitHub Bookmarklet Now Supports Code Search

I’ve added support for Github’s new code-search feature to Github Bookmarklet.

Get it

Drag this to your bookmarks bar: Github Search.

Code Search

As for user-search, but use the c: prefix. You can also use any of the GitHub macros as defined on the code-search page

c: badger language:ruby

Docs etc

 

Announcing GitHub Bookmarklet

You have to love GitHub! Just last week I was saying to Kamal on the phone that I now instinctively search for a project on GitHub before Google, because it’s likely to be there, and grabbing a copy or just browsing the source is made so easy for me.

What a shame it’s an extra few clicks to search it. Until now! Enter the GitHub Bookmarlet!

Install

Save the following link as a bookmark, or drag it to the links/bookmarks bar in your browser:

Over here → Github Search.

If you get stuck, Delicous have a lovely guide to bookmarklet installation.

Usage

When you click on the bookmarklet, it’ll give you a text prompt. Type in the name of the project you want to search for, and hit return. You’ll be taken to the GitHub search page for your query.

Hitting ESC or Cancel leaves your browser in it’s previous state.

User Macro

Want to search for a user? Type in ‘u:’ followed by your query. So for instance to look at Kamal’s github account, I would type in: u:kamal.

Hitting Return or OK now takes you straight to the user’s Github profile, or shows you a 404 if there is no such user.

Code Search

As for user-search, but use the c: prefix. You can also use any of the GitHub macros as defined on the code-search page: http://github.com/codesearch. c: badger language:ruby.

Acknowledgements

Future

If you have any suggestions, send me a message on GitHub, or fork the project and throw me a pull-request once you’ve made your changes.

 

Older Posts →

 

You Are Here


Douglas F Shearer

This is the homepage of Douglas F Shearer, a software developer and mountainbike racer. More…

Hire Me!


I'm available for hire. Ruby, Java and PHP work, both remotely (Worldwide) and locally (Scotland). Find out more or email me.

Flickr Latest


Stay Informed


What is RSS?

Categories


  1. Bike (89)
  2. Coding (84)
  3. Other (46)

Top Tags