Read my latest article: Ezra Zygmuntowicz -- Farewell, Friend. (posted Mon, 01 Dec 2014 17:53:00 GMT)

Planting the seeds

Posted by Sat, 05 Sep 2009 13:00:00 GMT

Yesterday, the Rails team released 2.3.4, which includes standardized way for loading seed data into your application so that you didn’t have to clutter your database migrations.

I noticed a few comments on some blogs where people were asking how to use this new feature, so here is a quick runthrough a few ways that you can use it.

Populating Seed Data Approaches

The db/seeds.rb file is your playground. We’ve been evolving our seed file on a new project and it’s been great at allowing us to populate a really large data. Here are a few approaches that we’ve taken to diversify our data so that when we’re working on UI, we can have some diversified content.

Basic example

Any code that add to db/seeds.rb is going to executed when you run rake db:seed. You can do something as simple as:

# db/seeds.rb

Article.create(:title => 'My article title', :body => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit')

Just create database records like you would in your Rails application or in script/console. Simple enough, right? Let’s play with a few other approaches that we’ve begun to use.

Use the names of real people

We’re using the Octopi gem to connect to github, collect all the names of people that follow me there, and using their names to seed our development database.

@robby_on_github = Octopi::User.find('robbyrussell')

# add a bunch of semi-real users
@robby_on_github.followers.each do |follower|
  github_person = Octopi::User.find(follower)
  next if github_person.name.nil?

  # split their name in half... good enough (like the goonies)
  first_name = github_person.name.split(' ')[0]
  last_name = github_person.name.split(' ')[1]
  new_person = Person.create(:first_name => first_name, :last_name => last_name, :email => Faker::Internet.email,
                             :password => 'secret', :password_confirmation => 'secret',
                             :github_username => follower, :website_url => github_person.blog)
  # ...
end

We do this with a few sources (twitter, github, etc..) to pull in the names of real people. If you want to be part of my seed data, you might consider following me on Github. ;-)

Use Faker for Fake data

You may have noticed in the previous code sample, that I used Faker in that code. We are using this a bunch in our seed data file. With Faker, you can generate a ton of fake data really easy.

person.links.create(:title => Faker::Lorem.words(rand(7)+1).join(' ').capitalize,
                    :url => "http://#{Faker::Internet.domain_name}/",
                    :description => Faker::Lorem.sentences(rand(4)+1).join(' '))

We might toss something like that into a method so that we can do the following:

@people = Person.find(:all)

500.times do
  generate_link_for(@people.sort_by{rand}[0])
end

...and we’ll get 500 links added randomly across all of the people we added to our system. You can get fairly creative here.

For example, we might even wanted random amounts of comments added to our links.

def generate_link_for(person)
  link = person.links.create(:title => Faker::Lorem.words(rand(7)+1).join(' ').capitalize,
                             :url => "http://#{Faker::Internet.domain_name}/",
                             :description => Faker::Lorem.sentences(rand(4)+1).join(' '))

  # let's randomly add some comments...
  if link.valid?
    rand(5).times do
      link.comments.create(:person_id => @people.sort_by{rand}[0].id,
                           :body => Faker::Lorem.paragraph(rand(3)+1))
    end
  end
end

It’s not beautiful, but it gets the job done. It makes navigating around the application really easy so that we aren’t having to constantly input new data all the time. As mentioned, it really helps when we’re working on the UI.

Your ideas?

We’re trying a handful of various approaches to seed our database. If you have some fun ways of populating your development database with data, we’d love to hear about it.

Git commit-msg for Lighthouse tickets

Posted by Mon, 16 Feb 2009 19:51:00 GMT

A quick follow-up to a post from a few months ago on how our team has a naming convention for git branches when we’re working on Lighthouse tickets (read previous post).

I’ve just put together a quick git hook for commit-msg, which will automatically amend the commit message with the current ticket number when you’re following the branch naming conventions described here.

Just toss this gist into .git/hooks/commit-msg.


  #!/bin/sh

  #
  # Will append the current Lighthouse ticket number to the commit message automatically
  # when you use the LH_* branch naming convention.
  #
  # Drop into .git/hooks/commit-msg
  # chmod +x .git/hooks/commit-msg

  exec < /dev/tty

  commit_message=$1
  ref=$(git symbolic-ref HEAD 2> /dev/null) || return
  branch=${ref#refs/heads/}

  if [[ $branch =~ LH_(.*) ]]
  then
  lighthouse_ticket=${BASH_REMATCH[1]}

    echo "What is the state of ticket #${lighthouse_ticket}? " 
    echo "(o)pen " 
    echo "(h)old" 
    echo "(r)esolved" 
    echo "Enter the current state for #${lighthouse_ticket}: (o)" 

    state="open" 

    read state_selection

    case $state_selection in
      "o" )
        state="open" 
        ;;
      "h" )
        state="hold" 
        ;;
      "r" )
        state="resolved" 
        ;;
    esac
  echo >&2 "[#${lighthouse_ticket} state:${state}]" >> "$1" 
    exit 0
  fi

Then a quick example of how this works…


  ➜  bin git:(LH_9912 ♻ ) git ci -m "another test" 
  What is the state of this ticket? 
  (o)pen 
  (h)old
  (r)esolved
  Enter the current state: (o)
  h
  Created commit 1ed2713: another test
   1 files changed, 3 insertions(+), 1 deletions(-)

Now to see this in action… (screenshot)

git message hook

Then we’ll check out the git log really quick.


➜  bin git:(LH_9912) git log
commit 1ed271323c4a054fe56e76bddc9ac81d241a1032
Author: Robby Russell <robby@planetargon.com>
Date:   Mon Feb 16 12:06:33 2009 -0800

    another test
    [#9912 state:hold]

Thanks to Andy for helping me figure out how to read user input during a git hook.

Lighthouse tickets and Git branching

Posted by Thu, 11 Dec 2008 17:36:00 GMT

We’re currently using Lighthouse as our ticketing system with clients for maintenance/bug requests. We’re also using Github for all of our major client projects. I’m sure that many of you take advantage of the Lighthouse service that Github allows you to use so that your commits can trigger actions on your tickets in Lighthouse.

If you’re not already, you might consider running (cheat ?):

  • cheat lighthouse

lighthouse:
  - Commit comment [#213]
  Adds message as comment to ticket #213

    * tagged - adds tag to the ticket (does not replace)
    * responsible - sets the user responsible for ticket (responsible:none to
    clear)
    * milestone - sets the milestone for ticket (milestone:none to clear)
    * state - sets state (new, open, hold, resolved, invalid)

  - Commit comment [#213 tagged:committed responsible:johan milestone:"Launch" 
  state:resolved]

With your commit messages, you can just pass in the ticket # and resolve your ticket without needing to interact with Lighthouse too much.

Okay, so one of the problems that I’ve had with this process is that I have had to constantly look back in my browser to see what the ticket # was that I was working on. So, I decided to start writing it down on a notepad as I was working through tickets so that I could look down at my desk, but this wasn’t terribly efficient either.

So, I decided to start leveraging the features of git to help me out. For each ticket that I work on, this is my process.

In Lighthouse, I decide which ticket I’m going to work on next. I then create a local branch using the ticket # in the name. Example: LH_1623

The workflow ends up looking like:

alphaclone git:(master): git checkout -b LH_1615

alphaclone git:(LH_1615): <—I am using zsh and have it display the current local branch

I then work on this ticket. Since I’m working within the branch and my prompt reminds me what ticket # is being worked on, it makes it easy for me to add this into my commit message.

git commit -m "Fixed the do-whacky issue with data importing. [#1615 state:resolved]"

At some point, this will be ready to be merged back into master and pushed to Github.

git checkout master

git merge LH_1615

git push origin master

Github will take your commit message and pass it over to Lighthouse and your ticket will be marked as resolved automatically. This workflow has saved me a lot of time from navigating through Lighthouse and has also helped me stay focused on individual tickets throughout the day. Quite often, I’ll get interrupted by something non-development related and seeing the ticket # in my terminal helps get me back on task.

I’ve managed to encourage a few of the others at Planet Argon to adopt this ticket-based branch process as well so that when we need to collaborate on a ticket we publish the ticket branch to Github so that others can work on it as well. (happens a lot when a designer and developer need to work together on the same issue/feature)

Anyhow, just a quick little introduction to something simple that I did that has definitely helped me become a little more efficient throughout the day. Perhaps you have a better approach and/or tips for others that you’d like to share?

Related Posts

Managing Required Gems on Rails Projects

Posted by Thu, 27 Mar 2008 03:27:00 GMT

We’re starting a new project and I’m finding myself adding things to the code base that we’ve done in the past… hence the last few posts. As we’re doing this, I’d like to highlight some of the little things that we do on each project to maintain some consistency and in that process reach out to the community for alternative approaches.

I’m intrigued by the vendor everything concept, but we haven’t yet adopted this on any of our projects (yet).

What we have been doing is to maintain a REQUIRED_GEMS file in the root directory of our Rails application.

For example:


$ cat REQUIRED_GEMS

actionmailer
actionpack
actionwebservice
activerecord
activesupport
cgi_multipart_eof_fix
daemons
fastercsv
fastthread
feedtools
gem_plugin
image_science
mongrel
mongrel_cluster
mysql
rails
rake
RedCloth
Ruby-MemCache
soap4r
uuidtools

Everybody on the team (designers/developers) knows to look here to make sure they have everything installed when beginning to work on the application.

This has worked fairly well from project to project but since we’re starting a new project, I’m curious if anybody has some better ways to approach this. Should we look more seriously at the vendor everything approach or are there any alternative approaches?

RubyURL 2.0 on the horizon

Posted by Tue, 17 Jul 2007 03:23:00 GMT

RubyURL was a project that I built about 2 1/2 years ago as a late night attempt to see what I could build and deploy with Ruby on Rails in a night. It’s nearing 50,000 unique website links, has a Ruby gem that you can use with it, and rbot plugins.

I’ve rewritten it about three times in the past six months, to try out some new approaches, but haven’t deployed with a new version as I’ve been waiting for someone to help me with a new design. Chris has offered to help out and once we integrate his new design with it, we’ll be launching it.

Everything is not great in RubyURL land though. It appears that it’s become an easy target for comment spammers to abuse the site to generate rubyurls and paste those links in their spam comments. Several pissed off bloggers, forum administrators, and system administrators have emailed me to complain that I’m spamming their site. Sadly, even with a basic disclaimer on the site, they still like to blame me for their spam. It’s gotten common enough, that I’ve written a template email that I respond with that explains how the site works and that I’m not accountable for people posting links to my URL redirect tool.

You can see that it’s popping up around the net via a google search.

So, I’ve been trying to think of ways to make it easier for people to flag URLs as being abusive of the site. I’ve not come up with any elegant solution that doesn’t force the good users of the site to have more steps in their process to create a basic RubyURL.

The ideal (and current) workflow:

  • User navigates to http://rubyurl.com
  • User pastes in long url into text box/area
  • User submits form
  • User is provided with new (shortened) rubyurl
  • User copies the rubyurl and does what they want with it (generally… pastes into IM, IRC, Email, etc.)

Some people have suggested using a user system to do this, but I really don’t like that as a solution.

Another idea, which I built… and later removed from my new version, involved having the original url load in a frame, and then provide a way for users to flag it as ‘spam’, ‘nsfw’, or ‘dead’. Then, we could provide the user with a warning that the following URL was flagged before, are you sure you want to continue? I didn’t like this as a solution in this way as it felt very obtrusive to have a rubyurl frame at the top of the browser window.

One person suggested a captcha to try and verify that the user is human, but there are problems with this.

  • I really dislike captchas. ;-)
  • This doesn’t prevent spammers from using the ShortURL gem, which does everything via an API.

In regards to the API, this could be enhanced by requiring that everyone register an email address to get an API key, but only solves the API abusers.

I’m starting to brainstorm some solutions that specifically help the requests made through the web. I haven’t checked the logs enough yet to verify it, but I have a strong suspicion that much of the abuse is happening through a web-based bot, not through ShortURL… because Ruby developers are nicer than that. (I hope…)

So, I am curious… dear readers of my blog. How might you solve this problem without disrupting the user experience? Or, should I just stick with what I’ve got going and find a better way to respond to pissed off bloggers who think I’m spamming them?

Discuss…