Archive for the ‘Ruby’ Category

[Rails] Associations

Monday, January 14th, 2008

Yesterday I found out I had made a major boo-boo in setting up an ActiveRecord::Association.

Imagine a “Widget” model that is composited of serveral other fields. You might think to yourself.

“An Widget has a SKU ( housed in table ‘skus’ based on model SKU ), a widget has a color, etc.”

You then might model your code such that

    Widget < ActiveRecord::Base
      has_one :sku
      has_one :color
    end

And accordingly

    SKU < ActiveRecord::Base
      belongs_to :widget
    end

This is wrong.

You must think in terms of the most “atomic” element. What’s the relationship of a SKU? A SKU “has one” product to which it is applicable. You see, what you’ve done above is absolutely reverse of the way it should be.

Think this way:

    SKU < ActiveRecord::Base
      has_one :widget
    end

And then just add the mirror entry, for completeness

    Widget < ActiveRecord::Base
      belongs_to :sku
    end

You can see this explained in the Rails API:

class Employee < ActiveRecord::Base
    has_one :o ffice
end

class Office < ActiveRecord::Base
   belongs_to :employee    # foreign key - employee_id
end

If you find yourself using the primary key of the composite entity to find something in the the constituent table or getting into weird sorts of problems with .create() or find yourself thinking that you may need to implement something like (although it is pretty cool):

    $ irb
    irb(main):001:0> class K
    irb(main):002:1> end
    => nil
    irb(main):003:0> k1 = K.new
    => #
    irb(main):004:0> k2 = eval('K').new
    => #
    irb(main):005:0> k3 = Object.const_get('K').new
    => #

[Reference]

The real difficulty here is with how English speakers construe the transitivity of the phrase “has one”. Does this mean:

  • X is a superior containing entity i.e. “contains” (“The happy meal has one hamburger and one toy”)
  • X is uniquely assigned in a relationship (“The parolee has one parole officer”)

The word “relationship” in the second bullet is the use of “has_one” that Rails uses the phrase “has_one” to signify.

If, when getting your object model to work in Rails seems really hard and sorta backwards, you should say “this seems needlessly hard, maybe I’m doing it the wrong way” and bail out of that design. The LOLCatz rules apply here: “Using Rails to make your life easy - ur doin’ it wrong

[Rails] Cleaning up HABTM views (2/2)

Friday, January 11th, 2008

You may want to see the previous entry on this topic. We’ll be using that application.

The reality is that most people use Rails for web frameworks … the console manipulation stuff we explored in the previous post doesn’t really help us much. We need a web interface. While using the script/generate gave us some scaffolds that we can play with ( http://localhost:3000/candies or ../flavors ), it’s not really “integrated” and it doesn’t quite demonstrate the “has many”-ness.

First we’ll fire up the web server (script/server) and see what the ‘new’ view looks like:

ss2.

Hm, that’s certainly not giving us any place to enter some flavorful information. Let’s fix that in the view.

(more…)

This is the mail that I sent to Rails-list which describes my issues around the Rails scaffolding in Rails 2.0. Extensive debugging information can be found in my diagnostic research post.


Hello,

I’ve read the (many) re-posts about problems around scaffolding in Rails 2.0 and have followed a number of tutorials and fully understand “how to scaffold” from a technical perspective, but I don’t understand the mindset of how to use the new scaffolding. It seems like a productivity- / agility- regress and I’m thinking I may have failed to properly grok the new setup. In the interest of full disclosure, I’m coming back to Rails after being in other toolkits for about 9 months.

Thanks to the intrepid work of Sean Lynch at ( http://fairleads.blogspot.com/2007/12/rails-20-and-scaffolding-step-by-step.html ) I found a tutorial that would familiarize me with the raw “how to scaffold” material.

I followed his tutorial’s step of:

“ruby script/generate scaffold Movie”

Great! From that point I filled in the “columns” in the migration as I had done in Rails 1.x. All I should need to do is run “rake db:migrate” and try adding a new record via the dynamically-created view.

When I started the server and navigated localhost:3000/movies I had the “create new” button. When I pushed that button there were no text widgets to enter despite having defined the columns that corresponded to said widgets having been added to the migration ( I have a lengthy blog post about how my diagnostics went, for anyone else’s edification ). In short the scaffold that had been created knew nothing of the columns I had added in the migration and, as such, the ‘new’ view had no widgets.

This struck me as well, wrong. On Sean’s post another user confirms the same experience. I have tried it with sqlite3 / mysql / postgres connectors.

Research showed that the scaffold had remained static relative to the time that I had done the original aenemic invocation. Per “script/generate scaffold —help”:

./script/generate scaffold post` # no attributes, view will be anemic

To fix this I had to re-issue the script/generate command with all the attributes in “final draft” mode ( “script/generate scaffold movie title:string text:description one_sheet_url:string” ) and then over-write the old templates ( output stored below, for legibility, Fig. 1).

The solution implies:

  • You have to get the script/generate command’s “attributes” arguments perfect at time of creation OR
  • You do this overwriting thing that I describe below.

As I recall Rails 1.x’s dynamic scaffolding allowed us to use a scaffold flexibly strictly based on migrations and rake db:migrate. This flexibility allowed us to “sketch” ideas very rapidly. Or is it considered a “Good Thing” that you get a “perfected” “generate scaffold” command at some point? If so, what’s the reasoning? Am I missing some sort of rake command that “refreshes” the scaffold templates?

Based on the comments at Sean’s site and some of the questions in the comments to DHH’s Rails 2. announcement I think there are others grappling with this quandry as well. Can anyone help?

Steven

(more…)

I decided to spend some of my Christmas break taking a look at Ruby on Rails again and trying to get an application together under this application stack. Since I last looked at Rails, it had crossed the 1.x to 2.x version marker and several changes manifested. For someone trying to follow the 1.x tutorials or the canonical reference book Agile Web Development With Rails, one doesn’t make very much progress before the changes with respect to scaffolding bite one. One may need a bit of a tutorial on Rails 2.x scaffolding before being “pretty close” to training documentation. An excellent tutorial for this content was found at [Fairleads][fl].

Yet as I followed this through, I found myself stymied by the same error reported by “James”

Thanks now I easily understand how scaffolding changed in 2.0.

But I still have a problem when I followed the tutorial everything went fine but i am not presented with any sort of fields to enter information.

And when i add stuff to the database by hand and I list from within the scaffold I am not getting the information that is entered into the database I am just getting a blank entry.

At first I thought my problem was that I was trying to use a PostgreSQL back end, or perhaps it was because I was using MySQL, etc. But nevertheless I still ran into the same problem no matter which db back-end I used.

I then found another tutorial at [SapphireSteel][ss]. Curiously, this worked ( the db back end was sqlite3 ). This tutorial is meant to show off the Sapphire Steel product, but Huw, the author, has added, graciously, a “here’s what Rails is doing on the back end” translation for each step that his product automates.

With these data points my working hypothesis was this:

  • Use SQLite3
  • Follow Huw’s instructions, which use a more specialized invocation of “script/generate scaffold” ( control )
  • Duplicate these instructions using a more primitive invocation of “script-generate scaffold” that’s more familiar ( experiment )

    (more…)

So far this first week of vacation has been used, as Lauren astutely noted, as, effectively, study hall. This weekend was largely spent preparing for my Latin probatio on Tuesday. The good news is that I managed to catch up on all the optional exercises in the back of my Wheelock’s and I had an interesting opportunity to learn more about extending Textmate.

I have discussed elsewhere the power curve of the editor emacs versus vim, but think that Textmate may have hit the sweet spot in terms of writing extensions.

Extension 1: Writing Macrons

While I had earlier posted about my joy of finding a keyboard map which would allow me to enter macron-ized vowels with Option + Vowel, I found this to me a very straining key combination on my keyboard. It’s not that easy to hook a thumb under to hit option plus a vowel.

Thanks to my crazy remapped keyboard, where Control is where Caps Lock is, I was able to remap Control + Vowel -> Macronized Vowel. This is a much better typing arrangement ( try it: Push caps lock plus a/e/i/o/u ). Even nicer is that on a Dvorak keyboard, all of these combinations can be hit with the left hand solely.

While this may be nifty, you say, I can say that it’s even niftier because I was able to scope the effectiveness of these bindings to be within certain types of documents. While emacs and vim certainly both support this feature it was incredibly easy to implement in Textmate. I simply scoped this command set to be within the text.html scope and it was carried into text.html.markdown ( an HTML shorthand ) text.html.textile and good old text.html itself. This is huge, huge, huge. This means that when editing PHP or Perl code Control + “e” or macronized-e reverts to its default setting of “end of line”. Very handy.

{ Aside: Astute readers may note that by assigning Ctrl+e to be macron I lost a handy mnemonic key-binding for go-to-end-of-line. I did, in fact. I have remedied this by adding, in that same scope Control + “]” as a replacement and that’s worked out pretty well so far. }

Extension 2: Speaking of Markdown

So key bindings and scoping may not be that big of a deal to you, but it was a huge step forward to me. Further, modal text editing is not something particularly foreign to vim or emacs. However, I had a few needs come up that would have been hairy to add in Vim’s scripting language, but that were incredibly easy to add with Textmate.

Ascii Table

Often when answering the questions in the back of Wheelock the question takes the form of:

  1. Identify the personal endings of the future and imperfect tenses of the first two conjugations. 1) -o 2)-s 3)….

Obviously, constructing the answer in a table would be preferable with column headings being the given number, the given ending, the identification / the translation / etc. But the code for entering an HTML table is, while simple, a bit of a pain to enter. It’s very tag-heavy. Textmate has not done the best job of making this process easier.

In the php-markdown-plus wordpress extension, suppotr was added for Ascii tables. Why this hasn’t been added for the Markdown master code base I have no idea.

Step 1: Create columns

There were six rows of data. Add plus one for the headers.

ruby -e ‘7.times{puts “|”}’

I type into textmate and push Ctrl+R. I get this:

 |
 |
 |
 |
 |
 |
 |

Textmate just let me type a Ruby one-liner into the text, hit Control R and insert the text. Not too shabby.

Step 2: Fill in the table headers:

|person|imperfect|future|
|
|
|
|
|
|

Step 3: Let’s fill in the given persons…

|person|imperfect|future|
|1st sg
|2nd sg
|3rd sg
|1st pl
|2nd pl
|3rd pl

Now it would be a pain to closs off all the row definitions with “|” by hand. I could use a search and replace expression like “s#$#|#g” on the highlighted range, but I wrote a simple key-binding to do that search and replace for me. I saved this add on into a bundle I created ( HTML Editing for Latin Students ) and voilá. Thus i hi-lit the section, control + | and…

Step 4: Close off newly-added column

|person|imperfect|future|
|1st sg|
|2nd sg|
|3rd sg|
|1st pl|
|2nd pl|
|3rd pl|

Now I needed to fill in the subsequent columns…I use control +n to go to the next line so that I don’t have to use the mouse or the arrow keys. It makes the vertical editing task much easier. This is an emacs convention. I close the process off with Control + | again.

Step 5: Finish off the table

|person|imperfect|future|
|1st sg|bam|
|2nd sg|bas|
|3rd sg|bat|
|1st pl|bamus|
|2nd pl|batis|
|3rd pl|bant|

and the future…

|person|imperfect|future|
|1st sg|bam|b?|
|2nd sg|bas|bis|
|3rd sg|bat|bit|
|1st pl|bamus|bimus|
|2nd pl|batis|bitis|
|3rd pl|bant|bunt|

Now, to my eye, this is an intelligible table. Nevertheless, I will need to convert this to an HTML table as Markdown doesn’t natively support this conversion. Now, if I were in emacs here, I’d need to break out some eLisp code. In vim I’d have to go through the hell of using the scripting metalanguage. With Textmate, I just write a ruby script and then paste that in ( it’s pasted after the jump ) and then bound that to a key-binding. Thus I have “Turn Ascii table into HTML” bound to Command-Option-T

<table border="0" cellspacing="5" cellpadding="5" style="">
  <tr>
    <th>person</th>
    <th>imperfect</th>
    <th>future</th>
  </tr>
  <tr>
    <td>1st sg</td>
    <td>bam</td>
    <td>b?</td>
  </tr>
  <tr>
  ...
</tr></table>

And that was incredibly handy.

Make styling with CSS easy

One of the things that made me choose HTML for my language of typing was the ease of styling. Per standard didactic purposes, there will be translation sections in exercises. I wanted to style the “given” one way and the answers another. Again, Textmate to the rescue.

Add a tab-trigger.

Typing: “pgiv(tab)”

<p class="sent_given">. </p>

I type a number (say, 11) then hit tab again and I’m inside the tag, typing the given.

Typing “pans(tab)”

<p class="sent_answer"></p>

Similar, but for answers. As both of these <p>-tag elements have classes associated with them, I can format them with CSS to get the look I want. Simple.

But wait, there’s more.

Doing ‘pans’ and ‘pgiv’ is inefficient. How about I type all the sentences at once, in paragraph form, start the paragraph with the question number to start at, and then have each of those set up as <p> tags with the “given” class associated with them?

11.  This is sentence one.  This is sentence two.  This is sentences three.

Highlight run through Ruby script I added called “Line-ify as Given sentences..”

<p class="sent_given">11.  This is sentence one.</p>
<p class="sent_given">12.  This is sentence two.</p>
<p class="sent_given">13.  This is sentence three.</p>

I’ve added other features like a corrections binding (corr-tab) to produce a span elemnent that’s colored red so that I can annotate errors, but I’ll stop here. You get the idea.

Textmate: Pretty, easy to extend with scripting languages you already know to key bindings you want in such a way that you don’t obliterate key bindings you don’t want to lose.

Conclusion

I’ve been so impressed by the power of Textmate in the regard of making HTML so much easier to generate, that I’m thinking about extending these features to LaTeX to get the beautiful formatting power latent there. I hopes this has helped you see that Textmate isn’t just a wonderful editor for code-hackers, it’s great for classicists as well!

(more…)

In March of this year I started the meetup.com group for the Ruby programming language. I wanted to meet some other people who were interested in exploring this elegant and rich system for the expression of thought.

Well, here’s the group!

Wisely, one of our members suggested that we work together on a learning project. Our project of choice was resolved last meeting and it is a ‘text-based adventure game engine’. The generic requirement is that by creating a scenario file ( i.e. the rooms, the contents of the room, etc. ) you can feed that file to the engine and it will give you a text-based adventure story along the lines of Zork or Leather Goddesses of Phobos.

I was so inspired by the discussion we had around this last week, that I wrote a basic set of classes for the construction and population of the universe. Our working model is that everyone will attempt the assignment and then at the next meeting we will compare approaches, decide on which model works, and then collapse those “winning” implementations into our main code branch.

Bit by bit we’ll all learn new aspects of Ruby and grow our own skills. Ultimately we may unleash our inner screenwriters and create a fun game or two.

This post is a ‘jumping off’ point for reading about my adventures at BNR’s RoR camp in February of 2007.

Day-by-day Recap

Summation / Preparation

Thanks Staff

Thanks to Charles, my teacher, and Emily and Jaye who handled the logistics. Big thanks to Aaron for coming out to check on us! Thanks as well to the Callaway Gardens staff who were so friendly and accommodating of a nerd invasion.

I had a good experience in the class. I was able to learn the material without falling behind, feeling like i was drinking from a firehose, or feeling like each additional word was just a drop of water on a saturated sponge. There were definitely people who feel more comfortable with the material right now than I do, but I thought I would like to tell you things in my background that I believe helped me be successful in the class.

Unlike a college institution, the BNR does not enforce pre-requisites. As such it is your responsibility to assess whether you have the tools and knowledge necessary to get what you need out of the class.

Rails stores its data in a Database: Know a relational database

Do I mean be a DBA? Be able to deploy Oracle with both eyes closed? No, I don’t mean that. I think you should be able to do a MySQL or PostgreSQL database set up ( you could probably just use a tutorial for either product ).

  • Basic DB concepts
    • What’s a relational database?
    • What’s a typical SQL query string?
    • What’s a primary key?
  • Basic DB skills
    • Run the command line to open a session
    • Create a database
    • Add / Delete / Describe a table
    • ( I didn’t have ) Knowledge about joins. This did not inhibit me, but having understanding of this too would have had me completely in the know.
  • Basic familiarity of DB use
    • Be able to run a SQL query on basic select parameters, be able to order by a criteria

Rails uses a web front end, know CGI / WebUI programming / HTTP issues about state

  • HTTP is a stateless protocol
    • Know what that means
    • Know techniques for preserving parameters between script reloads
    • Know how to write a basic form in HTML or Perl or PHP
    • Know how to pass a parameter in a ‘hidden’ form field
    • Know how passing form data in this format behaves when using a GET operation versus a POST operation
    • Experience writing CGI in either Perl or PHP will be hugley advantageous

If you’re on a Mac, Textmate is the editor to use

Some time playing with Textmate, how it tries to help you, how to use the bundle editor, maybe watching the screencasts is advised. Again, coming in with no experience is no loss, but if you have it you can r0x0r some s0x0rz.

If you’re on a PC, uhm. Sorry. I don’t have any knowledege about that.

Rails tries to use New Web Technology

  • Know CSS
  • Know a basic, modern, non Front Page, HTML file.

Rails is written using Ruby: know something about Ruby

Ruby …

  • Is object-oriented, you should understand object orientation
    • How would you define it?
    • What’s the difference between procedural programming and OO, why did OO evolve
    • Be able to describe the theory of a Class, Subclassing, an Ancestor class
  • Has a very interesting syntax, know a little bit about Ruby syntax
    • You needn’t be a guru, you’ll be writing Rails, which uses a fairly limited subset of the Ruby lexicon
    • Conversely, if you know a lot about Ruby you may be able to squeeze out new arrangements, you may be able to build more terse algorithms.
  • Data types
    • Know the basic data types: Hash, Array, and String
    • Be able to define you own data type ( == class )

If you know this, you should be able to breeze through the first day. You’ll be introduced to some Rails concepts, but they are mostly slight nuances of the above.

End Day 1 and beginning Day 2 will be your first solid Rails lessons and Day 3 will challenge you to incorporate advanced-core capabilities onto the core-capabilities you learned on Day 2.

BNR Classes are fun, it’s the hardest computer training course you’ll love busting your ass at:

  • Bring hiking shoes, there’s a daily walk after lunch ( weather permitting )
  • Bring business cards or have your .vcf file ready to go: you’re going to make friends and you’re going to want to give them your cards
  • Bring some wind-down material: Settlers of Catan was popular, the book you’re reading, some DVDs. Sometimes you may want to get away from the hub-bub and / or you may need something to help move you from ‘twitch mode’ to being able to sleep.
  • Check the weather. Who would have guessed that Atlanta would have been as cold as Kansas?
  • Be ready to work. Work as hard as you can to get a real understanding. Do the exercises, work to improve them, try to implement them again on your own, with slight modifications.
  • You may want to take additional time off to practice whet you’ve learned and / or to re-calibrate to “the real world”
  • A small umbrella might be handy, weather in the Gulf / South is unpredictable
  • Send me an email if you have a question or a comment!

Big Nerd Ranch: RoR Day 5, and back home

Saturday, February 17th, 2007

Well yesterday was a brief morning session where we covered profiling, how to get help, and took a look at some of the student generated work that had been created during the week.

After that we were shuttled back to Atlanta where we all dispersed, catching our flights to the various parts of the map.

My plane was delayed by an hour ( mechanical ) so I arrived in houston about 7:30. After getting to the park and ride I proceeded to drive back to Austin, getting home about midnight.

While I was flying I had a chance to post a wrap up and advice page which will be next in the posting list.

I’m glad to have gone, but right now, in my comfy chair, I’m sure glad to be back home!

Big Nerd Ranch: RoR Camp: Day 4: The Reprieve

Thursday, February 15th, 2007

Day Four: It’s a good day.

The reason day 4 is a good day is because you’re out of “how rich is this language and how many other key concepts must I learn to be functionally literate” phase. You see, you’ve covered the dead basics on the first day. Day two is a real challenge because you’re learning the bits of the language that are advanced and that you will need to know to really be able to work “out of the middle section of the book”: the part where it moves from introductiory to non-trivial.

Day three is the hardest, as I’ve detailed in great detail previously.

But day four is where the new and core material starts giving way to specialized topics: how to handle mail, how to build a test, how to provide web services. All of these build on the hard work you did on the first 2.5 days so you no longer get that feeling of “Oh hell, am I slipping too far behind?”.

Everyone in class seems to be a bit more spirited. The hardest part of our personal / night projects have been dealt with and everyone has that sense of “hey, you know, I might be able to do this on my own.” It’ the beginning of a very hopeful swing that continues into day 5.

Day 5 is the final bit of the “topics” specialized areas ( but not, not core language ), you learn to maximize particular aspects and you’re going home in just a few hours. It’s great to be at the Ranch, and you learn a lot, but just like all journeys it’s so good to go back home.

Once home you’ll reflect on the great experience you had and you’ll shake off the experience and re-integrate yourself into reality. But it’s so much fun, you can’t wait to get back to that mindset again.

Today was beautiful, but still cold. During our travels today we visited Callaway Gardens’ butterfly preserve. After walking through 40-degree weather it was quite a change of pace to enter the balmy 80-degree chamber in which the beautiful leipidopterans inhabit.

I’m still amazed by the versatility of the teacher, Charles B. Quinn. I mean, being able to take 30000.times{‘question after’} without snapping (verbally or mentally ) is really an excellent demonstration of guru-dom. I can only aspire to know some thing as well as the C. knows Rails, or as well as Aaron knows Cocoa (my previous BNR class).

Really I need a few days away from Rails, but I know that within the next week I’m going to start scratching in my notebook, imagining how I can turn BNR education into applications that amuse, entertain, and possibly do Something Great.