Amber Faith Elizabeth Silva Arrived Today! 1
Not bad for being 9.5cm dialated. The beauty of water birth.
5 minutes old
My, what big hands you have...
Back home 7 hours after we left.
Extending script.aculo.us 1
One of the great features of Rails is its plugin system. It allows you to add new functionality to the framework without modifying the original source. On my current project, I had a need to create a CachingAutoCompleter and I wanted to do it within Rails.
Rails has a method that will work just fine, text_field_with_auto_complete. The problem lies in the fact that this method creates an Ajax.Autocompleter, whereas I need an AutoComplete object with my caching functionality. I could modify the script.aculo.us source for Ajax.Autocompletor and add my caching layer but surely there's gotta be a better way, something akin to the Rails plugin system.
Click the image below to watch a screencast (7MB) of how I accomplished this goal.
You can download the source of the CachingAutoCompleter here.
Pig Semen has no negative side-effects
Having 5 (soon to be 6) kids is a real blessing, but really hits the pocketbook hard. Take food for instance, my monthly grocery bill is over $1000.
My wifes due date for our 6th child is today, Valentines Day, and we were thinking about using the good 'ol castor oil treatment to induce labor. My wife has a history of going a week or so past her due date, and with the Daytona 500 weekend coming up... well let's just say the last time I didn't watch the 500, Dale Earnhardt died.
WHAT? I'm a die hard race fan!
Anyways, I went online to research the safety of using castor oil to induce labor and ran across this article. It discusses the pros and cons of inducing labor, then goes on to describe what hospitals use to induce labor. PIG SEMEN of all things nasty in this world.
Considering we've had two of our children induced, I'm happy to report there are no side effects of this practice. Want proof?
ALL MY CHILDREN ARE PIGS
.Rebuilt the Date Helper Library 1
So I locked myself in my office Saturday and decided to rebuild the sorely lacking date_helper.rb that comes with Rails.
It was quite the daunting task for there were no less than 12 existing tickets for bug fix/enhancements. 17 hours later, a new date_helper was born that resolves all the issues and its quite DRY as well. Now we just gotta hope the developers get a chance to look at it sometime. Some of the fixes it contains have been around for ages so I'm assuming the core members don't use dates very often in their applications.
Heres a CHANGELOG:
- Makes :discard_year work without breaking multi-attribute parsing in AR. #1260 #3800
- Adds html id attribute to each element. #1050 #1382
- Adds :index and @auto_index capability to model driven date/time selects. #847 #2655
- Add :order to datetime_select, select_datetime and select_date. #1427
- Make scaffolding work with database time values. #2489
- Added time_select to work with time values in models. #2833 #2489
- Added :include_seconds to select_datetime, datetime_select and time_select. #2998
- All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. #363
- Adds :date_separator to select_datetime. Preserves BC.
- Adds :time_separator to select_time. Preserves BC.
Rails acts_as_threaded Plugin 12
While tinkering around with the acts_as_nested_set act of ActiveRecord, I tried to build a threaded forum with it. I ran into some difficulties in that a nested_set is designed to only have one root. Obviously, in a threaded forum, each thread would be its own root. So after wasting a couple hours trying to make nested_set work, I decided to use what I consider to be the best part of Rails: plugins. "acts_as_threaded" was born 1 hour later.
While I used it to build a threaded forum in this demo, it's design was inspired by a different project at work. The acts_as_tree behavior could have worked, but I needed a better way of containing my children (much like in real life).
I've included an 11 minute screencast of building an ugly looking Threaded Forum, but the concepts are there. I can still remember spending many man hours with my programming team at Bravenet to design and build the forum product we offered there. If Rails existed back then, we could have built it in a day. (Leave me a comment on how the screencast turned out.)
Click the image to view the screencast of acts_as_threaded in use: (8 MB)
As usual, you can download the plugin here. I will submit it as a patch when I solidify it and create the tests.
If you are following the tutorial, here is the display code in full.
def display_threads(threads)
content = ''
for thread in threads
content << content_tag('div',
content_tag('div',"* " + link_to("#{h thread.title}", {:action => 'show', :id => thread.id}, {'style' => 'color: #00f'}) + " " +
content_tag('span', " by #{h thread.name} · #{thread.created_at.strftime('%b, %d %Y - %I:%M %p')}", 'style' => 'font:10px tahoma;color:#666;')),
'style' => "margin:5px 0px;padding-left:#{thread.depth*20}")
end
content
end
UPDATE: See how to do this without a plugin using native Rails functionality.
The Big Tease
Ruby on Rails Increases Apples Revenue Stream
One of the problems with todays society is the close-mindedness of its occupants. It's especially prevalent in the programming world. I typically refer to them as zealots. I'll list the 3 groups that I see as the most damaging to my profession below. (I'll get back to the title of the article momentarily, keep an open-mind as you read this, it has a happy ending.)
Programming Language Evangelists
This group comes in a variety of breeds. C, C++, C# Java, PHP, Ruby, Perl, Python, Delphi and Visual Basic. Take your pick and you will find programmers who utterly refuse to believe there could be any other option. I have yet to talk with another programmer that changed languages based on the 'but look at all the cool things my language can do that yours can't' argument. If anything, it just reaffirms that their language choice is that much better.
The Open Source Cult
Giving back to the open-source community is a choice not a requirement. It's when you tell me I have to, that you cross the line. I had a heated debate with an open-source zealot at work a few months back when we were going to modify a GPL'd PHP application and use it to generate revenue from our customers. We were not planning on redistributing the application, just hosting it on our site. He was adamant that we were legally and morally bound to submit our changes back to the author. Well, you don't have to go to Harvard Business School to understand the concept of competitive advantage. We were doing this to generate revenue not to feel good about ourselves. Before you thrash me, let me say that ALL of us use open source products to generate revenue.
Here's his email that started it all (emphasis added):
Hi Bob, GPL (General Public License): excerpted: "If you modify your copy or copies of the program or any portion of it, or develop a program based upon it, you may distribute the resulting work provided you do so under the GNU General Public License. Any translation of the GNU General Public License must be accompanied by the GNU General Public License." **PHPSurveyor is, in fact, GPLed. You would probably be better served by looking for code with a less restrictive license, if in fact you desire to incorporate it in a non-GPLed derivative. I would recommend looking for something licensed under the BSD scheme: http://www.opensource.org/*license*s/*bsd*-*license*.php Apple successfully used BSD licensed code (Darwin) to create their (very) proprietary OS X. Hope this helps! IANAL, but I have a pretty extensive background in licensing issues.Now, I am not a lawyer either, but I'm pretty sure even a lawyer would understand the difference between the words *may* and *must*. And just to be sure, I emailed the FSF for verification and got a reply from Zak Greant (a volunteer):
Dear Bob, The case you cite is not distribution under the terms and conditions of the GPL. Thanks for writing, Zak GreantVindicated! It's this kind of attitude and mis-understanding of the open-source movement that causes people to either love it or hate it. Life is full of choices, take away my choice and you take away my life.
MAC Lovers
These are the worst offenders of all. It's okay to believe in a product and have your own opinion of its merits over another platform, but to flat out refuse to accept that someone may have a different opinion or experience is a bit immature and ignorant. It's the my daddy can beat your daddy up argument from your childhood. For this specific reason, I have rejected even considering Mac for fear others might see me as a close-minded, immature idiot who's daddy got his butt whooped by his friend's Dad when he was 5 years old.And now, the rest of the story...
I've used Windows exclusively since 1995. Literally, the only time I have touched a Mac was when I tried to turn one on about 7 years ago. After 5 minutes of looking for the freakin power button, I finally swallowed my pride and asked for help, after all, I'm a computer professional, I know how to turn on a computer! I wonder how many drinks an engineer at Apple had before he thought of putting the power button on the damn keyboard.With that said, I'm at a point in my life where I'm trying things I never would have tried a few years ago. For instance, now I actually use the hot mustard they bring you with a plate of pork fried rice. On occasion, I even stick a few pieces of brocolli in my bowl at our local Mongolian restaurant.
Two weeks ago, I decided to put aside my trusty companion for so many years, PHP, and give Ruby a try; sorry PHP, you've been good to me, but its time to move on. Once again, I've reaped the rewards of having an open-mind and trying new things. Well, today, I made the biggest step of all. I'm not sure if someone spiked my Coke at lunch, but afterwards, I went back to my office and ordered a brand spanking new MacBook Pro with a 30" cinema display. While I'm a little anxious and a little excited, I do have one major concern about my decision.
Does it come with instructions for how to turn it on?
PS: I haven't told my wife yet, so keep it on the low down.
Defining Numericality 5
Now that I've been promoted to a management position, I don't get the opportunity to program as much as I'd like. I love sharing my knowledge of something I am passionate about and feel obligated to repay the debt I accumlated when I was learning how to program 10 years ago. So I monitor the Ruby on Rails mailing list for people in distress and throw on my cape and try to come to their rescue.
I had just such an opportunity last week, when this distressed soul wanted to validate that an input field was a positive integer.
This should be an easy one to figure out. validates_numericality_of sounds like the perfect remedy. As it turns out, validates_numericality_of only determines if its input is indeed a number. The only constraint you can specify is that its an integer as opposed to a decimal value.
My other choice would be validates_inclusion_of. Using the :in parameter to that method allows me to constrain the input value. I can specify that I want it to be within 0 and 4294967295.
validates_inclusion_of :int_field, :in => 0..4294967295Not very pretty or intuitive. I got to wondering why this functionality couldn't be included in the validates_numericality_of routine. 'Numericality' is made up of 2 parts. 'Numerical' and 'ity'. We all know what 'Numerical' means (of or relating to numbers) and 'ity' is used to convert an adjective to a noun. Basically, it means we have a number. Therefore, 'Numericality' doesn't inherently constrain the value of a number, and in my opinion, neither should validates_numericality_of.
:validates_numericality_of :my_positive_integer, :gte => 0 Problem solved. You can download this plugin, which extends validates_numericality_of with 7 new options:
- :gt - Greater than
- :gte - Greater than or equal
- :eq - Equal to
- :lt - Less than
- :lte - Less than or equal
- :even - Even number
- :odd - Odd number
Another lost soul rescued and now I must hang up my cape, return to my regular job and wait for another opportunity to jump into action.
UPDATE: This has been submitted as a patch against trunk.
http://dev.rubyonrails.org/ticket/3952
Defining Success
Enhancing Rails Errors 22
So here is my "improved" error_messages_for function.
<%= error_messages_for 'client', { :priority => ['first_name', 'last_name'], :attr_names => {'first_name' => 'Surely, your mother gave you a name?', 'last_name' => 'Suffering from Alzheimers are you?', 'gender' => 'Now I understand why your mother did not name you'}, :defaults=> false, :header => 'You need to correct {count} error(s) before we can save this {object}', :sub_header => 'What on earth were you thinking?' } %>
This will print out:
I admit, this is a bit cumbersome, but it solved the problem I had and for anyone else thats anal about little things like this, it will solve your problems too!
You can download the plugin here. To use the plugin, just extract it to your vendor/plugins directory in your Rails Project. View the README and add some spice to your errors. Let me know if you have ideas for improvement or you have any problems. Enjoy!
UPDATE: Just released version 0.2. This adds the ability to pass in an array of object names and have the errors consolidated into one container.
