This past weekend I participated in the 2009 Rails Rumble where I built MealEtte (a combination of Meal and Roulette). The purpose of MealEtte is:
Ever wasted more than 5 minutes figuring out what to eat for dinner tonight? MealEtte is for you. (If you haven’t wasted any time, please let me in on your secret.)
MealEtte is designed to take the guesswork out of meal planning. By entering your Recipes you’ll have access to the MealEtte Roulette O’matic. Using sophisticated computer algorithms, artificial intelligence, and computer-geekery the Roulette O’matic is able to pick random meals for your consumption.
So sit down, get hungry, and spin the wheel.
I entered the Rumble in order to learn about some new tools in the Rails community that I haven't had a chance to use yet. And learn I did. Here's a short list of my favorites, the full list is available on my team page:
If I had to pick my favorite three new tools, they would be:
Raphael
Raphael is a JavaScript library that makes working with SVG easy, which I used to animate the roulette wheel. I ended up with about 50 lines of code to draw a SVG dynamically, animate the wheel spinning, and to get a random recipe from the Rails backend. Here's a shortened version of function, if you want to see the full function it can be downloaded from MealEtte:
initialize_spinner = function(options) {
// ... options initialization removed ...
var R = Raphael(opts.container, 500, 500);
var img = R.image(src, -300, 000, 800, 800);
var value = 180;
$(opts.trigger).click(function (e) {
$.ajax({
// ... connect to the Rails backend ...
});
value += Math.floor(Math.random()*180) + 180;
img.animate({rotation: value}, 2300, function() {
// ... popup a facebox lightbox with the results
});
return false;
});
};
Here's a quick walk through of the main Raphael functions I used in the animation:
var R = Raphael() creates a SVG container at a specific DOM id that is 500x500 pixels.
var img = R.image(src, -300, 000, 800, 800); takes the url of the roulette image and embeds it into the container as a 800x800 image.
$(opts.trigger).click() binds to the "Spin Wheel" link which connects to the Rails backend and also starts the Raphael animation.
value += Math.floor(Math.random()*180) + 180; adds a random number of how many degrees to spin the wheel.
img.animate({rotation: value}, 2300, function() controls the animation of the image, in this case to rotate it a specific number of degrees over 2.3 seconds (2300 milliseconds).
I was very happy with using Raphael. I'm still working out how to get the animation smoother but Raphael was able to make it easy for me to simulate animation without having to use Flash.
inherited_resources
inherited_resources is a Rails plugin that creates resource controllers. Instead of having to duplicate the standard Object.new, respond_to, format.html that is common in Rails applications, you just have to inherit the InherietedResources class and it will setup the 7 standard Rails actions for you. It includes a metric ton of hooks and ways to override it's behavior. For example, I added a simple Content resource to MealEtte in order to post updates right to the site. Additionally, I wanted to use will_paginate to limit the amount of data on each page. My entire controller with an override for will_paginate looks like:
class ContentsController < InheritedResources::Base
respond_to :html
respond_to :js
before_filter :admin_required, :only => [:new, :create, :edit, :update, :destroy]
protected
def collection
@contents ||= end_of_association_chain.paginate(:page => params[:page] || 1, :order => 'id DESC')
end
end
The collection method is my override and it tells inherited_resources to add the paginate method call when it's finding a collections of resources (e.g. the index action in Rails). Other than that and my application specific authorization, all of the behavior is kept in inherited_resources so there's a lot less code for me to maintain. One side benefit of this is that means there is a lot less code I have to test also, since inherited_resources itself tests it's generated methods.
fast_remote_cache
One common failure pattern in the past Rumbles has been teams putting off deployments until the very end and not being able to get their application running before time ran out. My goal was to deploy as soon and as often as possible; preferably as soon as I finished a new feature. In order to do that, I needed something faster than the standard 5-10 minute deployment process. This is where fast_remote_cache came in. Using fast_remote_cache I was able to deploy and have the server running the latest code in under a minute. This means I could do a small deployment in the amount of time it takes a user to load a new page. I'm going to be switching all my deployments to use fast_remote_cache soon, there's no reason not too.
I ended up coming away from the 2009 Rails Rumble with a lot of experience about some newer tools and some great ideas on how to integrate them into older applications. If you haven't ever done a code spike or any other rapid development on an application before, I'd highly recommend it just for the learning process. I'm planning to continue development on MealEtte to see how these tools perform during application maintenance.
Eric Davis
Tagged: deployment javascript rails rumble
I'm an avid reader but I haven't gotten very deep into Computer Science yet, so I decided to ask on Twitter to find what other people have read:
What's the best computer science book you've ever read and why?
Some responses:
The best computer science book I've read is The Pragmatic Programmer. It was the book that got me interested in the craft of programming. If you didn't catch my question on Twitter, tell me what the best computer science book you've read in the comments.
Eric Davis
Tagged: books programming
RailsBridge is hosting the first Rails BugMash this coming weekend, on August 8th through August 10th. The idea behind the BugMash is:
RailsBridge has a lot of energy. The Rails Lighthouse has a lot of open tickets. With the help of some Rails Core team members, we're going to see what we can do to cut down the number of open tickets, encourage more people to get involved with the Rails source, and have some fun.
The BugMash will be held in the #railsbridge IRC channel with a few members of the Rails core and contributors to help. If you'd prefer working in-person, several groups have organized venues in San Francisco, Boston, Chicago, and New York.
The BugMash will also include a prize raffle. Several businesses have offered prizes for the raffle; ranging from hosting to training to books. Additionally, Exceptional is offering a 3 month plan for their service to all participants.
If you're interested in helping out the Ruby on Rails community, this weekend is a perfect time to get involved. Just having access to the advise of other Rails experts alone is worth a few hours of hanging out. I'll be there trying to get my first contribution into the Rails core.
Eric Davis
Tagged: bugmash railsbridge ruby ruby on rails
A friend recently wrote me asking for some advise about contracting, which I think would be useful for a lot of freelancers.
Eric,
It looks like I have a shot at a 3 month contract with Initech. I have a vague idea of what the going hourly rates are; but I don't know anything about negotiating monthly or weekly rates. Do you have any suggestions on how to work out what to ask for?
Thanks,
Peter Gibbons
Welcome to the hardest part about business, pricing. For this, the type of engagement will change the price. There are at least two general types of engagements, Contracting and Freelancing. The problem is, the terms are used interchangeably in the industry so you'll have to ask some questions to find out what they are looking for before rates even come up. To add to this confusion, the IRS might call the contracting relationship an "employee/employer relationship" and the freelance relationship an "independent contractor relationship".
Contracting
I consider contracting as a way for a company to "hire" an expert to help for a specific chunk of time. Aaron Erickson describes contracting as:
One way to think of the difference is that in contracting, you are strictly exchanging time for money, whereas in consulting, you are exchanging ideas for money. The act of contracting is highly focused on rate per hour and set of skills brought to the table. No other factors matter in the context of contracting, such as the intellectual property the firm as a whole brings to the table or the broader capabilities to staff a team of professionals and provide leadership to a project.
The Nomadic Developer: Surviving and Thriving in the World of Technology Consulting, page 40
When this is a contracting engagement you will:
- be paid for a full week (40+ hours)
- be working on-site for the majority of the time
- use their systems to do the work (e.g. computers, network)
- be "contracted" based on a time frame (e.g. for 6 months)
- be working exclusively for Initech
Freelancing
A freelance relationship is one where you are brought in to complete a specific goal. For software companies, this is typically to develop a product or service for the company. Compared to a contracting engagement, when you are freelancing you will:
- only be paid for the time you work and bill. 20-30 hours a week is common.
- be brought on for the project and then move on afterwards
- be able to charge a lot more than the standard salary. Amounts range wildly, but you can expect at least 35% more at the absolute bottom end (see below).
- be able to work wherever you'd like
- use your own systems to do the work
- be able to work for other clients at the same time
Summary
Since the different types of engagement vary widely, you will first need to talk with Initech to find out what they are looking for. This means you might need to go into the meeting with two different numbers in mind, depending on what they want. From the look of it, I'd guess they are looking for a contractor relationship.
One thing to watch out for is, who is going to pay payroll taxes. If it's you, then you need at least a 35% premium over your costs to pay self employment taxes. You should also check how the IRS would treat the engagement to make sure you are not becoming an employee without getting any employee benefits. The IRS has created a bunch of information and tests for you to see.
I hope this helps clear up some of the terminology and give you some tips on how to move forward. Good luck.
Eric Davis
Tagged: business freelance
I'm happy to release the Redmine Kanban plugin for Redmine. This plugin allows users to manage issues by following the Kanban style of project management, with bonus Javascript effects like drag and drop.
Getting the plugin
A copy of the plugin can be downloaded from Little Stream Software or from GitHub. Make sure to download at least version 0.1.1, there was a critical bug that was fixed.
The installation instructions are included in the archive's Readme.rdoc.
Features
- Global Kanban page showing the status of issues across projects
- Multiple "Panes" to show the lifecycle of an issue
- Incoming Pane
- Unstaffed Backlog pane
- Quick Tasks pane - issues without a time estimate
- Selected Tasks - Manager prioritized list
- Active Staffed Requests - issues in progress
- Testing Staffed Requests - issues awaiting testing
- Finished Requests
- Updates to Kanban view are saved to the issues
- Issue status
- Issue assignment
- Issue start date
Usage
This plugin requires some configuration so it knows your specific Redmine environment. The Readme shows a recommended configuration that I used during development. Future versions will allow more customizations like turning off some of the panes.
Once configured, there will be a Kanban link on the top left menu. This will bring up Kanban page, which has the entire logic of the plugin. Make sure you have Javascript enabled and then start drag and dropping the issues. As issues are dragged to the right panes, their statuses will be updated inside Redmine.
Project help
If you need help you can contact me or create an issue in the Bug Tracker.
Thanks
I would like to thank Bill Tihen from the Leysin American School in Switzerland for sponsoring this plugin. If you find it useful, send your appreciation his way.
If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please contact me. My company, Little Stream Software, specializes in the development of custom Redmine features and Redmine plugins.
Eric
Tagged: kanban plugin rails redmine ruby
I've just released another small plugin for Redmine, the Issue Due Date plugin. This plugin will automatically set the due dates for issues based their Version or Deliverable's due dates. I found this is useful to keep track of the latest date an issue needs to be completed by.
Getting the plugin
A copy of the plugin can be downloaded from Little Stream Software or from GitHub
Usage
The plugin entirely works in the background when Issues, Versions, or Deliverables are saved. The plugin handles three separate states:
Issue edits
When an issue is edited, the plugin will check:
- If the issue's due date has been set on the Issue or
- the deliverable has a due date or
- the version has a due date
If any of those are true, the issue will have it's due date updated. If multiple of them are true, the first one will be used.
Version or Deliverable edits
The plugin will also hook into Versions so when the version's due date is updated, all issues assigned to the Version will be updated if the issues:
- Do not have a due date or
- Have a due date equal to the Version's old date
Example:
- Version X with a due of 2008-01-01 and issues of
- Issues A (due on 2008-01-01)
- Issue B (due on 2008-02-01)
- Issue C (no due date)
Changing Version X's date to 2008-01-15 will update the due date of:
- Issue A to 2008-01-15. It has the same due date as the version, so it's "following" the version.
- Issue C to 2008-01-15. It did not have a due date so it was given the version's due date.
- Issue B's due date will stay 2008-02-01.
Deliverables follow the exact same behavior.
Version or Deliverable reassignments
When reassigning an issue to a different version, if the issue due date matched the old version date, the issue will change it's due date to match the new version.
Example:
- I have an issue assigned to Version A with a date that matches Version A
- If I change the issue to be assigned to Version B, then the date should change to version B's due date.
Deliverables follow the exact same behavior.
Project help
If you need help you can contact me or create an issue in the Bug Tracker.
Thanks
I would like to thank Shane and Peter from Shane and Peter Inc for sponsoring this plugin. If you find it useful, send your appreciation their way.
If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please contact me. My company, Little Stream Software, specializes in the development of custom Redmine features and Redmine plugins.
Eric
Tagged: plugin rails redmine ruby
I attended Open Source Bridge was last week, and have to say it was the best conference I've been to (I've only been to half a dozen). The variety of content kept the conference interesting and it was nice for me to finally meet others in the Portland tech community. I took a bunch of notes during the sessions and wanted to summarize them here.
Wednesday, June 17th
Welcome Session
The welcome session started with some statistics that I thought were interesting:
- About 400 people attending
- 25% people are presenting
- 33% speakers are female
How to earn an open source living without taking investors or selling your soul
Brian Jamison from OpenSourcery talked about running a business that generates revenue from Open Source. He had a lot of good ideas, some of which I'm going to try out in Little Stream Software. My favorite idea was something we should all do more often:
"Say No, a lot
- Specific customer
- Sweat equity
- Microsoft projects
- Scope creep
- Lowering price - you've lost if the customer asks"
Open Source tools for freelancers
Christie Koehler, a Portland freelance developer, went over several open source tools she used. She mentioned a small Python utility called timebook. It's a command line program that you can use to keep a running timer for tasks. I'm going to try it out for a few days to see if it can replace my paper timelog I keep.
How to build a successful open source software consulting company
Nate Aune from Jazkarta talked about starting an Open Source Consulting company. I already consider Little Stream Software an OS Consulting company, based on the work I do for Redmine but I did pick up few ideas on how to generate other streams of revenue (without selling my soul):
- Custom development
- Training
- Support
- Hosting
Information Security for the Open Source Business
Kevin Kenan gave a session on Information Security. Sadly, it was targeted at larger businesses than so many of the ideas weren't useful to me. A good idea I did get was that products should give their customers a guide showing how to configure the product securely along with the tools needed to test those security precautions.
Cluster Analysis - how to have fun in n dimensions
In Jesse Hallett's talk, showed how to do some Statistical analysis (Cluster analysis) to visually group data. It was a very interesting talk, though above my current math knowledge. He did have pretty animations though.
How to Work with the Government for fun and profit
I made a change at the last minute and decided to go to Deborah Bryant's session on how smaller businesses can win Government projects. I haven't had a lot of chances to work with larger organizations so I wanted to know how feasible it is to work with the local government.
Thursday, June 18th
Thursday Keynotes
The opening keynote for Thursday included a talk by the Portland Mayor, Sam Adams. He mentioned that Portland has a lot of funds for digital improvements but there isn't enough people trying to help. This might be a good opportunity for local tech businesses to pick up some work.
Ward Cunningham gave the next keynote about Innovations in Teamwork. One of his suggestion was that we try to work together more often, because that will lead to more insights and solutions than we have now. Based on that advise, I'm going to try to attend more local user groups.
Unit test your database
David Wheeler from PostgreSQL Experts Inc gave a talk about unit testing the PostgreSQL database. Even though Ruby on Rails doesn't use all of the features for each database, this talk had a few points that are great for writing unit tests against non-database code:
- Test Driven Development is not for finding bugs, it for your own sanity and checking code consistently
- If testing an interface is hard, then the function might need to be refactored. Hard to test means hard to use.
- Tests are about as fast as your code but even then... they are much faster than debugging.
RubySpec: What does my Ruby do?
Brian Ford from Engine Yard gave a talk about RubySpec. I'm really excited about this project because he talked about some very easy ways to get involved and contribute. RubySpec is being used by many of the major Ruby implementations in order compare their implementation against the standard Ruby (MRI).
Configuration Management Panel
I went to this panel looking for a system that would help me automate server setup for myself and my customers. I was looking for something that was easy to use and that would make doing system upgrades simple. After hearing everyone speak, I'm going to take a look at puppet and automateit for my needs. The recording of this session just came online at blip.tv, I'd recommend watching it just to see the panel make offhand remarks at the other projects.
Bootstrapping Your Open Source Business
The GitHubbers never fail to entertain. Some notable quotes:
- "Taking VC money is like marring a girl"
- "I'm the CRO. Chief Revenue Officer"
- "100,000 users on Twitter is the best integration test ever"
Git vs bzr smackdown
Selena Deckelmann and EmmaJane Hogbin paired on a session comparing git to bzr. bzr was my first exposure to a distributed version control system but git was the first one I really understood. From what Emma and the audience were saying, bzr is easier to learn and is good if you work with Windows. They also put up two sites to continue the battle: bzrvsgit.com gitvsbzr.com
Friday, June 19th
Friday was the unconference day. I didn't take many notes but I think Friday was still my favorite day just from the networking and discussions that came up. I'm going to have to attend more unconferences in Portland.
That's my write up of Open Source Bridge. I really enjoyed myself and would highly recommend attending next years conference. If anyone wants some more details about the notes I took, email me me and I'd be happy to send you a copy.
Eric.
Tagged: business git open source open source bridge osb09 osbridge ruby
Earlier today I launched my very first Sinatra app, OnSafari. OnSafari is a tool to check if a book is available on Safari Books. I'm been a member of Safari Books for several years now and I'm constantly wondering if a book I'm looking at at a bookstore is on Safari or not. OnSafari will let me enter the book's ISBN number and will search Safari Books' website for the book.
Technology
My main goal with building OnSafari was to learn a few new technologies that I haven't had the opportunity to use yet.
Sinatra - Sinatra is a micro Ruby framework for building websites. It was very easy to pick up and learn how it works thanks to the documentation in the Sinatra Book. I'm definitely going to be using Sinatra again.
HAML - HAML is a templating language that uses white space to generate a HTML document. I didn't like the idea when I first heard about it but after using it for OnSafari, I'm starting to warm up to it. The templates are a lot easier to read but I did run into some unhelpful parsing errors. I think I'll give HAML another try on a future side project, but I'm not ready to recommend it for a customer project yet.
SASS - SASS is part of the HAML project and does basically the same thing but instead builds CSS files. I started to use SASS for the basic design. Once I integrated the final design though, I ended up dropping SASS in favor of vanilla CSS. Like HAML, I'd like try SASS out on a side project before I recommend it.
nokogiri - nokogiri is a HTML and XML parser. Since Safari Books doesn't have an API, I had to page scrape to "search" for books. I've already used Hpricot so I decided to give nokogiri a try. I had no problems with it, even when parsing Safari Books' JavaScript laden pages.
Heroku - Heroku is a hosting environment for Ruby Web application. I decided to try and host OnSafari on Heroku since they have been marketing themselves as the "Instant Ruby Platform". They really aren't joking, I was able to setup and deploy OnSafari in 15 minutes. That included making some code changes to accommodate their (lack of a) file system.
Summary
Overall, I'm very happy with the results of OnSafari. I learned a lot and was able to successfully build a site I've been wanting for awhile. I think my biggest surprise was how easy it is to host on Heroku. I'm now considering moving several other applications to their service, so I don't have to administer their servers anymore.
If you have a Safari Books account, I'd appreciate it if you would give OnSafari a try.
Eric
Tagged: haml ruby sinatra
As any community grows, it will encounter challenges. Depending on how the members respond, the community will grow, shrink, or even be wiped out completely. Last week the Ruby on Rails community was presented with a challenge during a regional conference. Without getting into the details, the community mishandled the challenge and hurt many members of the community. Instead of complaining about the incident, I decided to team up with some other people in order to try and improve the community.
After talking with Mike Gunderloy and a few other Rails community members, we started up RailsBridge. The website explains the purpose of the project perfectly:
The RailsBridge Mission: To create an inclusive and friendly Ruby on Rails community.
The RailsBridge Guidelines:
- First, do no harm. Then, help where you can.
- Bridge the gap from aspiring developer to contributing community member, through mentoring, teaching, and writing.
- Reach out to individuals and groups who are underrepresented in the community.
- Collaborate with other groups with similar goals.
The website has some more information about the project's goals, but my goal is to make the community more welcoming to new members. To do this, I'm going to be helping out with project Dana Jones is starting, Creating Courseware for Newcomers to Rails. If you would like to help make some positive change in the Ruby on Rails community, sign up for the group and let your voice be heard.
Eric
Tagged: railsbridge ruby ruby on rails
I'm happy to announce the launch of one of my Redmine side projects, the RedmineBlog.com. It will be the official blog for Redmine and will be another place the community can meet and topics discussed. From the About page:
We will be writing about various components of Redmine and it's community including:
We will try to make our content general enough to be used by anyone who currently runs Redmine or is evaluating Redmine, but we are targeting a few specific types of users to start:
- Seasoned Redmine users who are looking for regular updates and upcoming news
- New users who need detailed information on a specific topic
- Ruby on Rails developers who are wanting to get into Redmine development
If you are interested in Redmine, I'd appreciate it if you would post any comments you have and subscribe to the RSS feed. Thanks.
Eric
Tagged: blog redmine