LouLou Bijoux Officially Launched
I just finished the new LouLou Bijoux website for my friend Leslie du Roure. Very happy with the result. Check it out and buy some jewelery!
I just finished the new LouLou Bijoux website for my friend Leslie du Roure. Very happy with the result. Check it out and buy some jewelery!
I grew up in a relatively poor state (Montana) where people work hard for a living. My parents are restaurant and retail business owners and they work very hard. The traditional business models for these types of establishments require endless dedication and time and the labor to run them is largely manual labor. In other words, in order for these businesses to succeed, everyone involved has to work hard from the proprietor down to the part-time dishwasher. If enough people aren't pulling their own weight, the business will fail.
Growing up in that environment and learning basic rules about running a business makes it hard to forget and becomes part of your character. In my case, I believe this to be true: I work very hard and expect the people I work for and the people working for me to do the same. The ideal result is that each person in this chain reaches their own goals through hard work. The reality is much different.
I find that people of my generation expect their goals to be reached and their profits to be made not by working hard, but rather by simply meeting the right people and placing themselves in the right places at the right times. I am not ignorant to the fact that networking and promotion are huge factors of success. I simply mean to say that all the networking and promotion in the world cannot make up for the absence of hard work.
Profiting solely by the hard work of others is not a phenomenon found only in my generation (Generation Y & Z) nor in my industry (Web/Software Development). At heart, I am a business man and I believe there is a place to profit once you've worked long and hard to make your vision a reality. There is an important distinction though between working hard to create a self-sustaining business model and simply being a middle man. You either create something larger than yourself or you just pay your mortgage.
The unfortunate result a lot of times is that the people with great networking and promotion skills end up running companies that require honest hard work to be successful. As a result, the company operates solely to benefit the principals and ends up relying entirely on hard workers to turn the profits. The best way to detect a company like this is to find out how long people stick around. When you recognize a company that has very few employees and has a rapid turnover rate, run for the hills!
Co-working spaces are an increasingly popular outlet for self-employed creatives looking for office space to call their own. Many people working for themselves can begin to feel cabin fever when working alone from home or in coffee shops. For myself, I know it has always been important to manage my own time and yet still be productive. Besides keeping that in balance, there is always the need to network with new people and to collaborate closely with clients and colleagues.
I decided the solution was to find a co-working space that was near my home and would have like-minded individuals attending on a regular basis. While working with BHAUSmedia on various projects, I began giving feedback on their plans for creating such a place here in San Diego. The result is The Hive and is now open.
Having this engaging environment to meet new folks and to bounce ideas around has quite honestly enhanced both my client relationships and solidified a lot of ideas I had previously abandoned simply due to lack of external reinforcement. For people who know they have good ideas and simply need the extra push, I highly recommend checking this place out.
P.S.
Jelly is held every other Friday at The Hive and is free to attend. The next one is this Friday April 10th, 2009! For more information, check out Come Jelly at The Hive!.
I'm excited to be posting photos of my parents' new pub in Missoula, MT. It is called Sean Kelly's: The Stone of Accord. Their first pub in Missoula is called Sean Kelly's: A Public House, but this will be a much larger place, with a liquor store and small casino.
Check out the photos below:




A couple of months ago I gave a presentation at SD Ruby on the Ruby web-framework called Merb. The talk has now been published to the SD Ruby Podcast. Take a look at the video here:
Over the past few months, Patrick Crowley and I have been working on the complete rewrite of the popular Cinema Treasures community website. With the overall goal of bringing more social functions to the site, we needed a way to track changes the community makes to Theaters and related information. In essence, we needed "activity feed" functionality akin to Facebook and other social networks.
While it is relatively straightforward to store changes (versioning) of a particular model, it is less trivial to track what changed in each version and who changed it. This could technically be considered "auditing", but that's not a very exciting name. I decided to go with the name Shadow, alluding to capturing and storing the shadow of a record at any given state (including its associations).
For visual reference, the figure below shows how you might use Shadow to generate user activity feeds:

The model code to achieve the above functionality (in this case showing the User activity for a Project with Milestones), could be:
class Project < ActiveRecord::Base
has_many :milestones
shadow :attributes => [:address, :description], :associations => :milestones, :attach => :user
end
The shadow code is currently hosted at Github and is a Rails Plugin. I have plans to convert this into a Merb-compatible RubyGem as well. For more information on using Shadow and the current TODOs respectively, see shadow and TODO.
Also, if you are running Edge Rails, it is possible to install this plugin with the following command:
$ ./script/plugin install git://github.com/TheBreeze/shadow.git
Otherwise, you'll need to run the following command (remember to change to your Rails app root):
$ cd /path/to/your/rails/app
$ git clone --depth 1 git://github.com/TheBreeze/shadow.git "./vendor/plugins/shadow/"; rm -rf ./vendor/plugins/shadow/.git
This evening I've been hanging out in #ruby-lang helping people out and just chatting about some more advanced Ruby topics. I decided to jump on the console and play around with some Ruby internals. If you're a programmer and are curious about Ruby but aren't sure where to start, this is the perfect article for you.
First and foremost, you'll need to have Ruby installed on your machine. Doing this is pretty straightforward, click here for help. Once you have it installed, you'll get a nice little utility called IRB which stands for Interactive Ruby. To start it up, open a console window and type:
$ irb
You'll be presented with the signature ">>" command prompt. To make sure everything is working, go ahead and do a "Hello, World" like so:
>> puts "Hello, World!"
If you get the following output, you're ready to go:
Hello, World!
=> nil
A good resource to bookmark is the RDoc Documentation for Core Classes. Now is a good time to open this up in a browser. Once that is open, go back to IRB and enter the following line of code:
>> Object.constants.select { |c| Object.const_get(c).is_a?(Class) }.sort
Let's break that line down a bit. Since Object is the root namespace/class in Ruby, the constants class method will return all the modules and classes defined within Object. Since that returns an array of constants (it is actually an array of strings for each constant), we'll want to slim down the list to only those that are classes. The const_get class method returns the constant and the is_a? class method tells whether or not a given constant descends from a given class. Then we sort that list. Returned should be the 65 or so core classes that make up the Ruby language, see below:
=> ["ArgumentError", "Array", "Bignum", "Binding", "Class", "ConditionVariable", "Continuation", "Data", "Dir",
"EOFError", "Exception", "FalseClass", "File", "Fixnum", "Float", "FloatDomainError", "Hash", "IO", "IOError",
"IndexError", "Integer", "Interrupt", "LoadError", "LocalJumpError", "MatchData", "MatchingData", "Method", "Module",
"Mutex", "NameError", "NilClass", "NoMemoryError", "NoMethodError", "NotImplementedError", "Numeric", "Object",
"Proc", "Queue", "Range", "RangeError", "Regexp", "RegexpError", "RubyLex", "RuntimeError", "SLex", "ScriptError",
"SecurityError", "SignalException", "SizedQueue", "StandardError", "String", "Struct", "Symbol", "SyntaxError",
"SystemCallError", "SystemExit", "SystemStackError", "Thread", "ThreadError", "ThreadGroup", "Time", "TrueClass",
"TypeError", "UnboundMethod", "ZeroDivisionError"]
If you really want to get to know Ruby internals, just go through that list and refer to the documentation I mentioned before. Since that is simply a list of alphabetized class names, some classes will be far more complex than others. Feel free to skip those that are unclear.
Also, if you want the same documentation from the website locally, you can use the RI utility as follows (for the Array documentation):
$ ri Array
Have fun!

Last week Google launched a new product called Google App Engine. The premise is simple: let Google handle the server setup (including your application stack), maintenance, and scaling. It also means you have to use Google as your data store.
As with all things, there are always bigger fish in the sea. Google is dead-set on being the biggest. It's one thing to use Google products for personal use such as e-mail, documents, and widgets but quite another to store your companies' data in their proprietary data store.
Internet companies generally derive their value in one way: their data. For every user your app (running on Google App Engine) attracts, Google also gains a user. This is why Google chose to have a top-level User type in their data store. At the very least Google should be paying you, because your Application is providing them with more users.
By giving away the one thing that makes your application valuable, you are in essence giving away your soul.
When I moved from my home state almost three years ago, I felt like I had everything figured out. In my own naivety, I believed that to see my dreams come true, all I needed was to slowly work at my ideas until they became the visions in my head. Still today I believe in this ideology to a certain extent, but I've learned that success and innocence are frequently at odds with one another.
The "American Dream" is not as simple as working hard and playing by the rules.
This past weekend a friend was talking about how in many countries around the world, it is normal and sometimes even expected for young people to leave their home countries (before entering the workforce) and travel for months on end. The idea behind this tradition is simple: when you leave your comfort zone and must adapt to new cultures and customs, it is more likely for you to gain a sense of compassion and understanding. This no doubt enriches you as a person and gives you an extra edge when returning to the workforce.
In contrast, young Americans by-and-large do not travel once they've completed their education. Instead they enter the workforce directly and may not travel overseas until their world-view is firmly planted, if ever. As a result of this, we've become a nation of dispassionate and widely apathetic individuals.
Remaining passionate and driven in the midst of mass conformity can at times be highly indemnifying and at others an immense burden. Can compassion only be gained through experience, or does my understanding of the principle give me something of a consolation? Perhaps it's time to travel abroad.
Some colleagues of mine here in San Diego have put together a new user group targeted at Web Standards. I think this is a great opportunity for anyone looking to meet some new people and learn a lot. It's pretty short notice, but if you stumble upon this post before the meeting, you should definitely check it out!
Information about the first meeting can be found at http://sdwebstandards.org/. I'll be heading down to the meeting. Hope to see you there!