.NET Newbie on Rails

comfort zones are for sleeping

Tuesday, September 25, 2007

Depot App: Heads Down

I really am coding the Depot app. I promise. I'm just not blogging about it right now.

This blog is as much for my use as anyone else's, so I fully intend to go back and document my thoughts as I worked through each Depot task.

Stay tuned.

Thursday, September 20, 2007

Task A: Mea Culpa

OK, so I got some stuff wrong. Sue me. The point of this blog is to show that a .NET programmer can learn the RoR way of creating web apps. That means I'm learning; that does NOT mean I already know this stuff.

I had some questions about my Product class, specifically these lines:

  validates_presence_of :title, :description, :image_url
validates_numericality_of :price
validates_uniqueness_of :title
validates_format_of :image_url,
:with => %r{\.(gifjpgpng)$}i,
:message => "must be a URL for a GIF, JPG, or PNG image"
Apparently Ruby likes to call these declarations, and they are executed when the class is instantiated. I'm still guessing about some things: in my head, I'm assuming that these are instance properties whose values get set by the constructor. Then when the validate() method gets called as the object is saved, it checks the value of these properties as part of the base validate() logic. Am I anywhere near right on this?

Saturday, September 15, 2007

The Depot App: Task A

In the spirit of my last post, I have decided to jump right in, dang the torpedos, and start writing the Depot app that's explained in Chapter 5 of the Hiney Book. As we move through the tutorial, Hiney pretends that we've got some chick sitting beside us telling what she wants (like they always do), and that we have the opportunity to RoR shine as a true Rapid Application Development platform, easily responding to her every whim as she reveals her inmost desires more and more while working through successive iterations. Turns out her inmost desires revolve around selling programming books, so apparently she's an uggo.

This app needs a maintenance feature for adding, editing, and deleting products in the database - that's the feature that we'll create first, or rather, that's the feature we'll have Rails create for us first. Before we can do that we must create a new Rails app and a database for our product data.

A while back, I told you guys I found an editor I like for Ruby on Rails programming. Well let me tell you what: RadRails makes what little RoR programming I've done so far dead simple. I won't go far into describing it; the main things I like about it are that it gives me a project-level view of the app I'm creating, formatted and color-coded editing for ruby code files and other types of files for my app, and easy non-console access to the various services I need while I'm creating a Rails app (WEBrick, MySql, etc.). You have to do a little bit of reading to get it set up and ready to use, but you're reading this so I assume you can read help files too. I told it I wanted a new Rails project called depot, and voila!, there it is, ready to start programming.

The only thing I haven't figured out how to do in RadRails so far is create a new MySql database (I'm sure you can use RadRails for that, I just haven't figured out how). So I brought up a console window and typed this:

c:\rubysandboxdepot> mysql -u root -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or /g.
mysql> create database depot_development;
mysql> create database depot_test;
mysql> create database depot_production;
mysql> grant all on depot_development.* to 'root'@'localhost';
mysql> grant all on depot_test.* to 'root'@'localhost';
mysql> grant all on depot_production.* to 'root'@'localhost';
mysql> exit

Then I created a .sql file called schema.sql and saved it to the db folder:

drop table if exists products;
create table products (
id int not null auto_increment,
title varchar(100) not null,
description text not null,
image_url varchar(200) not null,
price decimal(10,2) not null,
date_available datetime not null,
primary key (id)

Actually, it was a little bit different than this when I first created it, but that's what it looked like at the end of all the iterations for Task A. I won't bore you with the details of the changes. The thing that really struck me was how easy and it is to change things in this environment - instant gratification.

Now to create the Admin feature, all I had to do was go to the generators tab in RadRails and tell it I wanted to generate a scaffold called Product Admin. That got me a "model" file called product.rb, a file to create unit tests for product.rb, and a bunch of views for doing CRUD on Products. I love how Rails assumes you're a big boy, and that you actually intend to write automated tests for your code - I've spent the last couple of years learning about TDD in .Net (among other things), and I'm very impressed that Rails has support for this built right in.

So now the Product class -

class Product < ActiveRecord::Base
validates_presence_of :title, :description, :image_url
validates_numericality_of :price
validates_uniqueness_of :title
validates_format_of :image_url,
:with => %r{\.(gif|jpg|png)$}i,
:message => "must be a URL for a GIF, JPG, or PNG image"

def validate
errors.add(:price, "should be positive") unless price.nil? || price >= 0.01
def self.salable_items
:conditions => "date_available <= now()",
:order => "date_available desc")

I've got some questions I'm sure will be answered in due time as I learn about Ruby and about ActiveRecord, but for now there are some things that seem strange to me as I approach this from Redmond:

  1. Where are my properties? How does a Product know what information it needs to keep handy about itself? I imagine this is somewhere in the ActiveRecord pattern.
  2. All of those validates_* statements at the top of the class are static methods, I think. Are we overriding stuff in the base ActiveRecord class here? I know these things, along with the validate() method at the bottom of the class, are called when a product is saved. But what exactly is the mechanism that executes these methods?

The only other stuff we did in Task A was to tidy up the views a little - seems rather like old ASP code, but I'm sure there's a lot more stuff going on here.

Friday, September 14, 2007

Let's Kill Something

I have two large posters hanging above my desk in my den of programming iniquity. One shows a fuzzy kitten dangling precipitously on a clotheswire by his claws, with the caption, "Hang in there!" The other shows two vultures, and one is saying to the other, "To heck with patience! Let's kill something!" I keep them where I can see them because I feel they represent the two sides of the coin that is my personality, the yin and the yang, if you will, of what makes me...well, me.

You see, I could sit back and wait patiently, obedient to my supposed fate, and hope someone or something comes along to sever my bond of ignominy, whether it be the shame of my own fear and weakness in the face of seemingly insurmountable odds, or my exile to the shadows until the end that approaches us all overtakes some hapless soul, and I receive my carrion feast like crumbs from the table. Patience is indeed a virtue. But it becomes a tether when I know I could throw it to the wind, cast my lot with that impudent vulture, spread my leathery wings to fly off into the night's cold embrace, and eat my fill until the juice runs down my neck.

I considered the message of both posters this evening as I sat in my dim parlor of digital ephemera, abuzz with the whir of heat sink fans, the clicking of hard drives, and the crackle of Tesla coils. Surrounded by hand-rubbed mahogony wainscot alive with the musk of decades worth of linseed oil, I eased back into my leather chair, and scratched my black jaguar Mr. Tinkles on the chin as he squinted, flattened his ears, and purred his familiar blessing. I took a slow, deliberate swig from my snifter of cognac and gazed deeply into the gems (rubies, ironically!) set deep in the eyesockets of the polished silver death's head mounted atop my ebony cane, as I pondered my decision. And then it came to me:

Let's kill something. Starting with a fuzzy kitten.

To whom it may concern

My machine is now back among the living. After re-seating the CMOS battery, and spending some time on the phone with the good people of the Dell support center (yes, you read correctly), I have video again. Among other things, I apparently inadvertently put my flat panel monitor into digital mode last weekend, but my motherboard video out is VGA. Laugh if you must.

A summary of the “help” I’ve received so far:

  • “Dude, sounds like your motherboard’s fried.”
  • “Disconnect everything”
  • And my personal favorite, “Buy an iMac.”

I see how you guys are. Don’t worry, you’ll get yours…

Tuesday, September 11, 2007

A tale of woe, and a plea for help

Well, the worst has come to pass. I can only assume by your stunned silence that you have already guessed the source of my grief: that’s right, my graphics card on my home machine has died. This tragic event occurred last Thursday evening, and I have been basically without a machine to call my own ever since. For the bereft among you, I will bring the old board into my office tomorrow morning for a proper funeral. Viewing will be from 7:30 to 8:00 AM. In lieu of flowers, it is requested that donations be made to the .Net Newbie on Rails fund (cash only please, no personal checks). Needless to say, this is seriously cutting into my RoR programming and blogging. That ain't living, that's just barely surviving. Like a vampire eking out an existence on the blood of rats and birds he traps in the cemetery.

The machine in question is a Dell Dimension E521 with onboard video, but I can’t get a video signal from the onboard video, not even during POST. Nothing, nada, zilch (and no, the monitor is not the problem). I got a new card (EVGA 7300 GT) from Fry’s this weekend and tried installing it. Here are the scenarios I’ve tried so far with little or no luck:

1) Monitor hooked to fried card (well, obviously)
2) Monitor hooked to onboard video, with fried card still installed
3) Monitor hooked to new card
4) Monitor hooked to onboard video, with new card installed

Scenario #2 worked for a couple of hours on Sunday night, but it stopped working last night before I installed the new card – no idea why. None of the other scenarios has worked at all. Tonight I’ll try taking the new board out and going back to onboard video. Beyond that, I’m clueless as to what to do.

Here’s where you come in: HELP!!! I welcome any advice on getting this solved.

Austin on Rails meeting

Last night I went to the Austin on Rails meeting just for fun (I know, “Dude, you really need to get a life”). Man, this is where all the real nerds are: all hairy, poorly dressed, probably haven’t seen the sun in 3+ weeks, and all crazy smart. There was a lot of love in that room for people with poor grooming and few social skills.

Cool stuff though. There was a guy there from Amazon presenting AWS, particularly their “infrastructure as a service” stuff. Talked a bit about their Simple Storage Service, which is flexible storage you can access via a webservice priced under a scaled fee-per-use model, as opposed to a subscription for a big chunk of storage you may not ever use. He also quickly covered the Simple Queuing Service – the name says it all.

Then he went into the Amazon Elastic Computing Cloud service (EC2), which is basically a huge grid of virtual Linux servers that can be spun up dynamically via a webservice, again with a fee-per-service pricing model. This offers a pretty cool solution for apps with limited needs for bursts of scalability, as well as time-bound apps. You can set the servers to spin up on a particular schedule, or you can spin up new servers if your app’s performance characteristics pass some arbitrary threshold you specify. Some cool usages he mentioned were:
  • A company in India is using EC2 to process payroll once a month for several thousand employees.
  • Stanford Law School uses EC2 to process OCR transcription of millions of old legal documents.
  • The guy who presented created a time-bound app called ThursDate – a social network that only operates between the hours of 5:00 – 8:00 on Thursday night. The idea is that you have three hours to log on, upload pictures, videos, etc on Thursday night to find a date for Friday night. When the 3-hour session is over, everything disappears, and the app reappears anew next Thursday with no persisted info from the previous session. He has a chron job that spins up an EC2 image at the appropriate time, and the floodgates open.
Anyhoo, if none of this sounds remotely interesting, and you can actually get a date, you are to be congratulated: I commend you. However if, like me, you have no social life, these guys could be a pretty good support group: http://www.austinonrails.org/.