Archive for April, 2006

Rails: Easy Multiple Selects

Fish Creek Park

Large version here
Again, the geek content is high in here. If you don't give a rat's ass about web developement frameworks, or don't know what one is, you should just finish this visit with a look at the pretty picture.

First, and foremost, Rails is sweet. If you've ever spent any time dealing with a web development framework, as soon as you dig into Rails you will understand these people know the way that is it supposed to be. I remarked to a co-worker that the reason I like Rails is that the database, if done correctly, is transparent. You only need to deal with the logic of the objects, and their persistant storage is secondary.

Jerry and I have been embarking on a black hat operation to sneak more Rails into our application. Recently, we've been looking at an alarming alert mechanism. Within the workings of this particular application I came across some implementation details regarding Rails that I thought I'd share with those that found me through google, just in case I've delt with this problem before you have.

Implementation details have been changed to protect the innocent.

Let's pretend we need to keep track of rubber duckies and the bathtubs that they are found within. Being that I'm coming from a DBA background I'd like to make the database objects first

create table rubber_duckies (id int not null auto_increment, name char(64), primary key (id));
create table bathtubs (id int not null auto_increment, name char(64), primary key (id));

Rails has an amazing amount of magic to deal with references. We want a rubber ducky to be able to go to multiple bathtubs (You never know when Ernie will visit), and a bathtub should be able to house more than a single ducky. This n-to-m relationship can only be encapsulated in a reference table, so create the table:

create table bathtubs_rubber_duckies (bathtub_id int not null, rubber_ducky_id int not null);

You need to put the references in alpha-numeric order for this work. So because we are dealing with bathtubs and rubber duckies we need to respect that bathtubs are first in alphanumeric order. Of note: You can't put an ID column on a reference table, or Rails will puke.

Now we need to tell the Rails models that we have a relationship between the database objects. So after you've generated the scaffold you can edit app/model/bathtub.rb to read:

class Bathtub < ActiveRecord::Base
        has_and_belongs_to_many :rubber_duckies
end

and app/model/rubber_ducky.rb to be:

class RubberDucky < ActiveRecord::Base
        has_and_belongs_to_many :bathtubs
end

Now that we've established that a ducky can be found in multiple bath tubs and that a bathtub can have multiple duckies, we're finally down to the meat. Most of the hard work is already done because of the strict naming we used in our tables. Firing up the console at this point will show you that a rubber_ducky object will have a collection of bathtubs attached, and vice versa.

From the front end, we want to be able to assign a Rubber Ducky to any number of bathtubs through a multiple select box, so we modify app/views/rubber_duckies/_form.rhtml and add:

<p><b>Bathtubs</b></p>
<% selected = @rubber_ducky.bathtubs.collect {|bt| bt.id.to_i } %>
<select name="rubber_ducky[bathtub_ids][]" size="3", mutliple="multiple">
<%= options_from_collection_for_select Bathtub.find_all, 'id', 'name', selected%>
</select>

The naming of your multiple select with tell rails that the information you are sending back is a list of bathtub identifiers for your ducky that you are editing or creating.

Now, we have support for a multiple select that allows for a subset of a collection to be saved to an object. I've dealt with other frameworks, and with most it's not this nice.

Comments

PhotoFriday: Famous

Best Shot

An interesting challenge for this week's PhotoFriday. At first I was thinking celebrity, and I knew that I couldn't win that battle. I figured I'd go with the infamous pyramids of Giza, as I'm sure almost everyone has heard of them.

Comments

You Do What?

Serial Killah

Yesterday, Wes managed to lock his keys in his truck at the A&W parking lot. Not a great bit of luck, but still a managable problem. Since I didn't live that far from said eating establishment, we walked over to my place and picked up a coat hanger. I was once a chevy owner, and Wes currently owns a GMC, we both knew how easy it is to break into his truck. When we got back to the parking lot there was a tonne of cars around, and I was wondering if someone would call the cops.

I pried the door away from the frame while my partner in crime started fishing for the lock inside the truck. After a few minutes my fingers couldn't handle it, and we decided on another plan of attack. We wondered over to the other side of the truck where the door latch could be pulled away from the body far enough to get the coat hanger inside.

By this point we had an audience, and in particular one older gentleman who was watching us from the mini-van parked next to us. After we fished around for a couple more minutes we had a muffled click and the door swung open.

It was at this point that the wispy old man finally spoke to us. He came out chatting about "I wondered if you boys would get that open", and murdled about Wes appearing to be "Full of fire". After a few more seemingly random phrases, he told us that he was a licenced lock smith.

How stupid is that? Your business acumen must be pretty sad when you sit and watch a potential client struggle with your particular craft.

Comments

PN: 12335587

Molded plastic and rusted metal

My car has been giving me a little grief recently. A shimmy going around a corner here, a little spot of oil on the ground there, you can tell that this six year old can feel the four hundred thousand kilometers she's already travelled over.

Since some of the repairs aren't out of my control, I decided to fix a couple on Sunday. After I managed to get my hood latch working properly, I tackled the quickly blinking right hand blinker. I knew that the problem was going to be that something wasn't working on the circuit, which was causing the blink time to decrease. So I flipped on the signal light and quickly found the offender.

After I layed out on the ground and grunted and groaned to get the light out of it's little abode, I pulled the bulb out and noticed that there was oxidization everywhere. It would appear that the seal wasn't quite waterproof and the metal tongues through which the bulb would get it's daily fixin' of electrons, were rusted right out. Well, that just won't do.

I hopped in the car, and travelled to most of the major part stores: Auto Value, Princess Auto and Part Source. Each venue was the same "I'm sorry buddy, we don't stock that, you could try the dealership". Given that Auto Value's tagline is We've got it, I knew the kid behind the counter didn't have anything to do with it, so I put on my jock strap and proceeded to the stealership.

Even after I made the decision to take a kick in the junk to get my part, the pain did not stop. I started out going to Carter's. Cahrter's brags about being the largest warehouse of parts for GM make vehicles in western Canada. Well, they didn't have it, but they told me that McKay did. So I drove down to McKay Pontiac/Buick, and they didn't have it, but they told me that Shaw did. So I continued driving about, sucking back more than my fair share of $1.10/liter gasoline, until I finally had the hot little part in my hand. $45.90 later, I started to ponder how society has evolved to a state where a peice of molded plastic with copper running through it can cost more than a week's worth of food. Nevertheless, I had it now.

Right in the stealership parking lot, I layed down on my back, plugged in the socket, pushed in a bulb and cursed and cussed as I put the socket back into the pot. After a couple of nasty cuts and pinched fingers, I finally had the whole thing back together.

Although, when I tried it out, it still didn't work.

Comments

Now It’s Over

Calgary Sundown

Larger version here

Another action packed weekend has closed, and now I come to the part of the week where I spend more of my time doing stuff for someone else.

Friday, I meandered down to Bottlescrew's to take in the first game of the Flame's playoff run. With the Edmonton game going into double overtime and the Flames also going into knuckle whitening OT, the night was definitely great for hockey.

Saturday I was up early for my first ever attendance to the Basement Bowl. Chad was nice enought to host the LAN party at his house, and we murdered each other electronically for most of the waking day. The biggest problem with attending something like a LAN party is explaining it, because a good number of people don't really know exactly what one is; Furthermore, once you put the entire debacle of a group of guys people dragging their computers together in order to lower latency doesn't quite make sence to the non-technical. Well, we still did it, and had a blast. I was king of the hill when it came to RTS, being on the winning side most often, and always finishing with the highest of scores. On the FPS side however, I was a walking joke. I was killed so humiliatingly, so many times that I was contimplating better spending my time making a bullseye for my soldier's back. Nevertheless, the fun had to end, and I went out socializing at Peter's place, where I caught the tail end of drama to a scale I have never seen before. Funny and tragic at the same time.

Sunday I managed to get around to some fix-me-ups that I've been putting off for a while. Now my plumbing works a little better, my garage door opens every time, my screen door won't go flying off in the wind and I have proper working chairs in my computer room.

In the evening I went out and took in V for Vendetta. I read the graphic novel, and I would say I liked both the book and the Wachowski brothers shortened it. There really was a whole lot more going on in the novel, as is to be expected, but the writers were really careful about what they took out and what they left in. They did change some key points at the end of the movie, but the overall flavour was preserved.

Comments