Chronicling my experiences with ruby on rails, web application development/management.

Monday, June 29, 2009

30 days of Rails - Hpricot parsing

Scenario - You need some information off of a website, but there are around 100 rows. This information will also need to populate the name column of your model, so you need to clean up the data. Bascially you need to parse information from a paragraph or one big string. This is where hpricot and some ruby come in handy.

html string parser - Rake task

Here is the code i ended up using, and will try and explain it at the end

namespace :sponsor do
desc "seed data"
task :seed => :environment do
require "open-uri"
require "hpricot"
doc = open("") { |f| Hpricot(f) }
@snag = (doc/"#cnnContentArea").inner_html
@snag.gsub(/<.*>/,'').split(/\n\t+/).map {|t| t.strip }.reject {|t|t=='' }.each { |t| Sponsor.create!(:name => t) }

Code explained

I needed to pull information from that actual url. All of this information lived within the div tag id cnnContentArea. inside the source of the html page, it was prepopulated with \n\t\t\t and the number of tabs varied.

Using hpricot, we open the url page and save it as an hpricot object (see the doc = line above.

Next, we take the saved page and pull out the content from the cnnContentArea div tag, and we save it as an instance variable @snag.

The last chunk of code, does the following:

  1. The @snag string basically replaces itself without any of the paragraph tags (that what gsub does).
  2. Next, the string is split into mini strings based on a delimiter, and in this case anything that matches \n followed by any number of tabs (\t). I was lucky to be able to do it this way.
  3. We then iterate through each mini string(that's what map is doing) and we then strip all whitespace, before and after the words in the mini string. (see the block t.strip
  4. As an added measure, if the mini array is empty, then it is rejected (courtesy of map)
  5. Lastly, we then take the clean mini string and add it to our model, which in this case is a simple Sponsor model under the name column in the DB.

I have to thank emitilin from IRC as he spruced up my code, but i do take solace in the fact that i knew where to go and now i have an even greater understanding of ruby and rails. I'm sure in the comments you can point me to a method that does this in one fail swoop, but when you are learning ruby, you are a winner when you get to apply the knowledge to a problem you need fixed.

Friday, June 26, 2009

30 days of Rails - Model Associations

You've picked the perfect model names for you new app, but you are unsure when to use a has many :through association or should it be a has and belongs to many association? Or should it be a simple many to many association. Wait, what about has_one and what the hell is a polymorphic anyways?

Well at this point in the game, you may understand what each of the Model Associations do, when you branch out from the basics, or don't use them for awhile, you end up forgetting when and where to use them.

In an effort to streamline the decision of when to use the various Model Associations available in your rails app, I've come up with a decision tree app called Model Association Decider. This decision tree will help you decide when to use a model association in rails. So use this app to determine which association you should use. Model Association Decider

Wednesday, June 24, 2009

30 days of Rails Series - Introduction

Well here i am. I've taken a good look at what i need out of my life, computeristically speaking, and have decided that I am going to sink even more effort into learning Ruby on Rails, the one true and just framework, praise be unto him.

Thirty Days of Rails.. WTF?

What I've decided to do is document, a post a day for a month, about what i've learned in my rails journey from today moving forward.

I will focus on rails methodologies, techniques, optimization strategies, and anything else that i end up learning.

What the 30 days of Rails isn't...

This isn't a beginners class. I won't explain myself as indepth as I would, had I started from scratch. I'm starting with a loose grasp of rails knowledge obtained from a year and a half of using the framework. That means, i know how to do shit, but i want to learn MORE so that i can create apps trouble-free from here on out. Since I've made it my journey, I will pass these tidbits on to you, the gentle reader.

So let's see where this thing ends up. I take it that I'll probably end up with a lot of posts regarding TDD/BDD testing as i know sweet fuck all about it,however, I will post what i do find out, hoping it helps someone down the road.

Populating Select menus in Cucumber

From the easy when you finally know what you are doing, column....

How the hell do you setup a select menu in a feature?

Well, it turns out it's easy. Not obvious to me, as nothing is in this testing BDD world, however. Basically For every select menu you want to use in a feature, you must create a Background scenario to populate that select menu before every feature is ran

Here's the code

Feature: Manage Driver lineup as an admin
In order to manage all drivers
As an admin
I want to be able to create and edit a list of drivers.

Given I create a series "Nascar"

Scenario: Login as admin
Given I am logged in as an admin
When I go to the admin homepage
And I follow "New Driver"
When I fill in "Name" with "Darryl Waltrip"
And I select "Nascar" from "Series"
And I press "Create"
Then I should see "New Driver saved succesfully"

Nascar and all other known shit in the code above is copyright of their respective entities. I am just using it as an example, so chilax

Now in the background step you can just create the list of series(as i have it) using factories as so...

Given /^I create a series "([^\"]*)"$/ do |arg1|
Factory(:league, :name => arg1)

Enjoy. yes it was easy, just no one told me how to do it, so i thought i'd see if i could help another soul out.

Monday, June 22, 2009

Important Cucumber step that must not be missed!

Ok, this may just be an aha moment for myself, but i always thought that when i looked at ryan's screencasts on Cucumber we're overly weird. That's right, i said it.

Now, why were they weird? Well, he started out his steps by including the following kind of Given statements:
Given I have zero articles
# or
Given I have an article named "Cheese"

Without this step at this time, there is no way to follow a article_path("blah") link at all. In my simple mind's eye, i thought there would be.

Lessoned Learned?

Stop being a moron and setup your Given statement to either start with a record or two for the model you are trying to BDD against, or make sure NONE exist, to start with a clean slate.

Saturday, June 20, 2009

Rails vs Pylons - initial thoughts

I know, I know! Comparing two frameworks is bound to be riddled with generalizations that don't help anyone and obvious features that are only "ah ha" moments to the writer of the post. However, I'm going to give you an account of my initial thoughts of Pylons, as compared to ruby on rails, a framework that I've been using for a year and a half.

Comparing Pylons to Ruby on Rails

Initial thoughts are how very similar these two frameworks are. Pylons basically admits that it takes well founded queues from rails. But who wouldn't?

If you were to design a framework today, and you think it through, any MVC framework will smell like rails, which has hundreds of contributors, all tweeking the code base. When a populist approach takes hold, you end up with some "trueisms"

All Pylons has done, from my inspection so for, is taken those trueisms as a starting point for their framework, and now are building off that on their own direction.

Common Features between Pylons and Rails

Here is what I noticed, 24 hours into trying Pylons, as it compares to Rails:

  • File structure is similar - Rails and Pylons both create a whole bunch of files to the project folder. Pylons however has more files outside of the project's directory that are used to setup information about the egg file. Think of an egg as a ruby gem, i guess.

    Again, notice that inside the QuickWiki root folder, you have a QuickWiki folder where all your code goes into. This to me, looks like what we'd see in rails. Also, notice the models, Views(Templates) and Controller is mingling with the public folders, etc...

  • Routes - these seem similar, down to the map.connect. however, i've yet to find out if they implement Restful routing. They do seperate their controller commands by controller and RestfulController, so time will tell. Again, it's just been 24 hours. On first impression, Pylons routing actually can do a lot more, then what i've seen in rails. If this feature exists in rails, i've not seen or read about it in a year and a half. In Pylons, the first routes are the ones handled last, where as in rails, the bottom of the routes file gets executed last. Here is the example from their tutorial:

    Notice again, that last line before the return. If you entered a url "/whatever" and it doesn't exist, the last route will create the page for you, based on it being the title. That title variable is passed to the show page and saved in the DB. Perfect for wiki applications. I don't think I've seen that in rails, to date.

  • Environments - Both Pylons and Rails have development, test and production environments. In pylons it appears that the environment files are housed in the outer file system, see image above to get what i'm saying. the inner file system appears to be where you'd put most of your code for the MVC part of things. Now in part two of this post, i'm sure to have written about production deployment and the differences there. if not, screw you Lulz.

  • Error Pages/ Debugging - Both have a cool stack error printout on your browser, when you fuck up. However, Pylons is interactive and you click on these arrows to get to the right code from within your browser. You can also send Pylons an email right from the error page, if you wanted.

Differences between Rails and Pylons - initial thoughts

I know i added some variances above too, but here is a list of things that is really different between the two frameworks:

  • You are making an Egg file, not a web app. - Ok, this is my spin on the whole thing, but technically you are making a python egg that will just happen to be served through the web. In rails, we are creating a web application in ruby. Not a ruby gem, not a ruby script, a full on independent web application whose sole purpose is to be viewed through an internet browser.
    While i may be putting it too simply, it was something to get used to that when you are coding you are technically creating a python egg file that you can either, give to your friends to play around on their computer, or serve it through the web, or what have you. Maybe this has to do with the fact that you are creating a WSGI application. Read Pylons concepts here for more details.

  • Pylons needs to be running in a Python virtual environment, in order to work. What that means is you can't just call Pylons create -t MyProject willy nilly. No big deal, just something to get used to.

  • Pylons uses something similar to ActiveRecord, but in the python world it's called SQLAlchemy. From the pylons site: SQLAlchemy is a powerful Python SQL toolkit and Object Relational Mapper (ORM) that is widely used by the Python community.

  • No Migration files - All migrations are setup in the file of the models directory. Personally, rails has it right, with it's easy to understand migration creation, in my opinion. However, Pylons isn't hard, it's just, well, more.

  • Templating Engines - Instead of ERB, they use Mako, by default. It's not that strange when learning mako, as some of the nomenclature is similar.


Both have their pros and cons. I don't mind Pylons, and I'm going to try and create a project in Pylons, something other then the wiki from their tutorial. I'll be bloging my way through that project, and giving you the usual uncandidness you've been accustomed to. If you want to expand your web framework knowledge past rails, Pylons is a good choice to start with, without the huge learning curve.