Read my latest article: 8 things I look for in a Ruby on Rails app (posted Thu, 06 Jul 2017 17:59:00 GMT)

The HTTParty has just begun

Posted by Thu, 27 Nov 2008 01:54:00 GMT

After releasing the new RubyURL API, I decided that it was time to look around at libraries to interact with it. I came across a new Ruby gem from John Nunemaker named, HTTParty, which aims to make it easy to talk to XML and JSON-based web services. Be sure to read John’s announcement of HTTParty.

So, I decided it might be fun to introduce more people to the gem by showing you all how to use it to talk to the new RubyURL API.

Install HTTParty

Before we get started, you’ll need to install the HTTParty gem with the following command:


   ~ : sudo gem install httparty
  Password:
  When you HTTParty, you must party hard!
  Successfully installed httparty-0.1.6
  1 gem installed
  Installing ri documentation for httparty-0.1.6...
  Installing RDoc documentation for httparty-0.1.6...

Great! Now that we’re ready to party hard, let’s build something.

Talking to the RubyURL API

The RubyURL API currently supports both XML and JSON, which are each supported by HTTParty. The great thing about HTTParty is that all you need to do is include it in a class and you’re able to quickly talk to remote services.

In this following example, we’re going to create a new class called Rubyurl.

class Rubyurl
end

What we’ll want to do now is include the HTTParty library. (note: you’ll need to require both rubygems and httparty gems and I’ll skip those lines in following code samples)

class Rubyurl
  include HTTParty
end

The HTTParty provides a few class methods, which we can use to configure our library. We’ll go ahead and specify the base_uri, which we’ll set to rubyurl.com.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'
end

Now that our class is setup to talk to the Rubyurl.com site, we’ll want to add a new method which we can use to communicate with the RubyURL API. We’ll call this shorten as we’re using RubyURL to shorten long URLs… right?

class Rubyurl
  include HTTParty
  base_uri 'localhost:3000'

  def self.shorten( website_url )
  end
end

Our new shorten method will expect us to provide it with a website url, which we’ll want RubyURL to return a shortened URL for. The PATH for the API that we’ll want to talk to is: /api/links, which we’re expected to pass XML or JSON to.

Here are two examples of using the RubyURL API with HTTParty.

RubyURL via JSON w/HTTParty

We’re going to use the post method that is provided with HTTParty to send a request to /api/links.json. As you can see, we’re providing the original website url to the web service.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'

  def self.shorten( website_url )
    post( '/api/links.json', :query => { :link => { :website_url => website_url } } )
  end
end

When ran, it’ll produce the following:

  >> Rubyurl.shorten( 'http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb' ).inspect
  => {"link"=>{"permalink"=>"http://rubyurl.com/uJVu", "website_url"=>"http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb"}}

Pretty simple, eh?

RubyURL via XML w/HTTParty

The great thing about HTTParty is that you can use XML without changing much.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'

  def self.shorten( website_url )
    post( '/api/links.xml', :query => { :link => { :website_url => website_url } } )
  end
end

Produces the following

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<link>
  <website_url>http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb</website_url>
  <permalink>http://rubyurl.com/uJVu</permalink>
</link>

Closing thoughts

So… there you have it. HTTParty makes it extremely easy to interact with various web services that work over HTTP. I’d encourage you all to take a few minutes to experiment with it and see what crazy ideas that come to mind during the process. :-)

Lesson Learned: Git Ref Naming

Posted by Fri, 19 Sep 2008 04:23:00 GMT

Our team has been working our way into the Git world. One of our big client projects is now 100% git while the other is still on Subversion for another month or so. (I’m getting by with git-svn, the gateway drug on that). We’ve had pretty much nothing but success with Git for quite some time, but recently this repository started to get chaotic, which has eaten up time… which isn’t conducive to productivity.

So, I wanted to share a quick lesson that we learned today after scratching our head for a while. It’s important that you avoid having a branch on a remote repository that shares the name of a tag in your local and/or remote repository.

I REPEAT.

It’s bad mojo to have a tag and branch share the same name. Things that you’d expect to just work... don’t. This was causing us to see warnings and errors like the following, which we weren’t really sure what to make of it.

“warning: refname ‘staging’ is ambiguous.

“error: src refspec staging matches more than one.”

This started about two weeks ago when we started a few new remote branches: staging and design. It seemed to be going okay but we managed to muck up things when we merged those two together and some of us were having success fetching/pulling/pushing to staging and others were having to specify :heads/staging and couldn’t have a local branch named staging. Needless to say, it was causing some problems and slowing us down.

This afternoon, we finally noticed in the GitHub interface that there was a tag named staging. Hmm… interesting. We verified this by using git show-ref.


git:(master): git show-ref | grep staging
6a18119ca9.... refs/heads/staging
82caa5f121.... refs/remotes/origin/staging
6a18119ca9.... refs/tags/staging

Notice the tag reference at the end? After asking in #git, we were able to remove the tag with the following:

git tag -d staging

Then we needed to remove the reference of staging on Github with git push origin :staging. (we got rid of the remote branch temporarily as well so that we could clean this up).

The next step was to push our local branch back out to the remote branch git push origin staging:staging.... and now we’re back in business with a simple:

git checkout --track -b staging origin/staging

Anyhow, if you end up having those warnings/errors above, you might take a look at git-show-ref to see what is in your local repository as this could be causing you some unnecessary headaches.

Kudos to Allison for taking the time to really read and digest the git documentation, which helped us figure this shit out. :-)

Since we’re still learning to get around through things like this, if you have any more insight into this issue, feel free to help educate us a bit by sharing your wisdom in response to this post. :-)

RSpec: It Should Behave Like

Posted by Wed, 20 Aug 2008 02:47:00 GMT

I was going through an older project of ours and cleaning up some specs and noticed how often we were doing the same thing in several places. When we started the project, we didn’t get the benefits of shared groups. Now that we have some time to go through and update some of our older specs, I’ve been trying to take advantage of the features currently available in RSpec. One feature that I haven’t seen a lot of mention of by people is shared groups, so I thought I’d take a few minutes to write up a quick intro to using it.

To pick some low-hanging fruit, let’s take an all-too-familiar method, which you might be familiar with… login_required. Sound familiar? Have you found yourself stubbing login_required over and over throughout your specs?

describe Admin::DohickiesController, 'index' do

  before( :each ) do
    controller.stub!( :login_required )
    Dohicky.should_receive( :paginate ).and_return( Array.new )
    get :index
  end

 ...
end

If you’re requiring that a user should be logged in when interacting with most of the application (as in the case of an administration section/namespace), you might want to consolidate some of your work into one shared specification group. The basic premise behind this is that you can write a typical describe block and load it into any other spec groups that you need. For example, in our case, we’ll need to stub login_required in several places. We can set this up in one shared group and reference it wherever necessary.

For example, here is what we’ll start off with.

describe "an admin user is signed in" do
  before( :each ) do
    controller.stub!( :login_required )
  end
end

describe Admin::DohickiesController, 'index' do
  ...

However, the new describe block isn’t accessible from the block at the bottom of the example… yet. To do this, we just need to pass the option: :shared => true as you’ll see in the following example.

describe "an admin user is signed in", :shared => true do
  before( :each ) do
    controller.stub!( :login_required )
  end
end

Great, now we can reference it by referring to it with: it_should_behave_like SharedGroupName. In our example above, this would look like:

describe "an admin user is signed in" do
  before( :each ) do
    controller.stub!( :login_required )
  end
end

describe Admin::DohickiesController, 'index' do
  it_should_behave_like "an admin user is signed in"

  before( :each ) do
    Dohicky.should_receive( :paginate ).and_return( Array.new )
    get :index
  end

 ...
end

describe Admin::DohickiesController, 'new' do
  it_should_behave_like "an admin user is signed in"

  before( :each ) do
    @dohicky = mock_model( Dohicky )
    Dohicky.should_receive( :new ).and_return( @dohicky )
    get :new
  end

  ...

That’s it! Pretty simple, eh? We can now reference this shared group in any describe blocks that we want to. A benefit to this approach is that we can make change the authentication system (say, we decide to switch it entirely and/or even just change method names, set any other prerequisites necessary when an admin is signed in), we’ll have a single place to change in our specs. (tip: you can put these in your spec_helper file)

You can learn more about it_should_behave_like and other helpful features on the RSpec documentation site.

If you have any suggestions on better ways of handling things like this, please follow up and share your solutions. I’m always looking to sharpen my tools. :-)

Update

In response, Bryan Helmkamp suggests that a better solution is to define a method in our specs like, for example: build_mock_user_and_login. then calling it in our before(:each). So, maybe the approach above isn’t the most ideal method but I did wantt o draw some attention to it_should_behave_like. I suppose that I need a better example.. another post, perhaps? :-)

Also, Ed Spencer has posted an article titled, DRYing up your CRUD controller RSpecs, which will introduce you mor to it_should_behave_like.

Thanks for feedback people!

Related Posts

Learning Git without getting your SVN feet wet

Posted by Tue, 11 Mar 2008 06:59:00 GMT

Our team has been migrating towards using Git as our primary SCM. We have way too many Subversion-based projects and repositories to just do a clean switch over and not everybody on the team has had time to start playing with it. Baby-steps…

So, for those of us who want to use it day-to-day, we’re using git-svn.

Andy Delcambre has posted the first in a series of blog articles to help you pick up on using Git on Subversion-based projects. Check out his article, Git SVN workflow to get up to speed.

Also, if you’re on OSX and using Git… check out Justin Palmer’s new project, GitNub, which describes itself as, “a Gitk-like application written in RubyCocoa that looks like it belongs on a Mac.” This looks promising. :-)

Get to Know a Gem: Rak

Posted by Tue, 11 Dec 2007 17:10:00 GMT

A few months ago, I posted about an article that showed you how to colorize your grep search results. Since then, I’ve heard people talking about ack, which describes itself as…

“a tool like grep, aimed at programmers with large trees of heterogeneous source code.”

It’s written in Perl, which is fine and dandy… but before I installed it, I heard that there was a Ruby version named rak, which describes itself as…

“a grep replacement in pure Ruby. It accepts Ruby syntax regular expressions and automatically recurses directories, skipping .svn/, .cvs/, pkg/ and more things you don’t care about. “

Sounds great. Let’s see what this thing can do.

Installing rak

Daniel Lucraft, the author of rak, was kind enough to package it up as a Rubygem. So, all we have to do is install it via gem install rak.


   > sudo gem install rak                                                                                                                                                                                                     
  Password:
  Bulk updating Gem source index for: http://gems.rubyforge.org
  Successfully installed rak-0.8.0
  Installing ri documentation for rak-0.8.0...
  Installing RDoc documentation for rak-0.8.0...
  ~ >

Great, let’s move on.

Using rak

Now that it’s installed, we can use Rak by typing rak from the command line. You’d typically want to run this from within the root of your application.

For example, basic usage would look like the following.

$ rak search-pattern

In my first test, I ran rak README.

Immediately, I see a greater advantage to rak over using grep and that’s because it’s giving me line numbers for free, which takes remembering a few extra options with grep.

Like grep, we can specify a specific path to search with. For example, we use a view helper named link_to_unimplemented to help us track actions that aren’t implemented yet. Looking at a current project, I can run rak link_to_unimplemented app/views and produce the following results.

I’m going to keep playing with it, but wanted to help get the word out. If you have any tips on using it, please share them in the comments. :-)

Multiple Database Connections in Ruby on Rails

Posted by Fri, 05 Oct 2007 22:54:00 GMT

We have a client that already has some database replication going on in their deployment and needed to have most of their Ruby on Rails application pull from slave servers, but the few writes would go to the master, which would then end up in their slaves.

So, I was able to quickly extend ActiveRecord with just two methods to achieve this. Anyhow, earlier today, someone in #caboose asked if there was any solutions to this and it prompted me to finally package this up into a quick and dirty Rails plugin.

Introducing… Active Delegate!

To install, do the following:


cd vendor/plugins;
piston import http://svn.planetargon.org/rails/plugins/active_delegate

Next, you’ll need to create another database entry in your database.yml.


login: &login
  adapter: postgresql
  host: localhost
  port: 5432

development:
  database: rubyurl_development
  <<: *login

test:
  database: rubyurl_test
  <<: *login

production:
  database: rubyurl_servant
  <<: *login

# NOTICE THE NEXT ENTRY/KEY
master_database:
  database: rubyurl_master
  <<: *login

At this point, your Rails application won’t talk to the master_database, because nothing is being told to connect to it. So, the current solution with Active Delegate is to create an ActiveRecord model that will act as a connection handler.


  # app/models/master_database.rb
  class MasterDatabase < ActiveRecord::Base
    handles_connection_for :master_database # <-- this matches the key from our database.yml
  end  

Now, in the model(s) that we’ll want to have talk to this database, we’ll do add the following.


  # app/models/animal.rb
  class Animal < ActiveRecord::Base
     delegates_connection_to :master_database, :on => [:create, :save, :destroy]
  end

Now, when your application performs a create, save, or destroy, it’ll talk to the master database and your find calls will retrieve data from your servant database.

It’s late on a Friday afternoon and I felt compelled to toss this up for everyone. I think that this could be improved quite a bit, but it’s working great for the original problem that needed to be solved.

If you have feedback and/or bugs, please send us tickets.

Older posts: 1 2 3