NH Seacoast Ruby/Rails UG

Posted over 7 years back at zerosum dirt(nap) - Home

I just got word that there’s a Ruby on Rails user group starting up in my area. It’s being organized by Scott Garman and the first meeting will be January 16th at the UNH Library in Durham, NH. More details at Scott’s Blog. It’ll be great to meet some other local Ruby dorks — most of my contract work is non-local and the other devs I know in the Portsmouth area have sadly yet to be bitten by the bug. I’m psyched that someone has taken the initiative to set this up. Thanks Scott!

On completely unrelated news, I’ll be afk for a few days. Heading northbound to visit relatives and then some college friends for a New Years’ extravaganza of sorts. Hopefully I can remember how to play beer die — it’s been awhile. See y’all in 2007!

To-Do List Demo

Posted over 7 years back at The Hobo Blog

I’ve posted another demo – this one is a simple to-do list app (see the Demos section). The app took about 10 - 15 minutes to create, which includes figuring out the (minimal!) design.

This demo illustrates a little more of what you can do with the permission system. Each to-do list has a public? attribute. Public lists can be viewed by any visitor to the site, whereas private lists can only be viewed by the owner of the list. Here’s a couple of fragments from the TodoList model that show how we set this up:

class TodoList (fragments)

belongs_to :user
has_many :tasks

def viewable_by?(viewer, field)
  viewer == user or public?
end

Clearly we want this view permission to carry over to the individual tasks in the list. First we define public? and owner methods on the Task model:

class Task (fragments)

belongs_to :todo_list

def owner
  todo_list and todo_list.user
end

def public?
  todo_list and todo_list.public?
end

The owner of a task is the owner of the to-do list it belongs to, and a task is public if it belongs to a list and that list is public. Note that the implementation of these rules is no longer than the descriptions I’m giving in English. Now we can define view permission for the task:

class Task (fragment)

def viewable_by?(viewer, field)
  viewer == owner or public?
end

Run up the demo and have a look at the way these permissions effect the user-interface, as seen by a guest user, a signed in user, and the administrator (to create the administrator, just sign up as “admin”). Are there any holes? You might notice that the front page gets a little out of whack. This is because at the moment there’s no way to count the number of public to-do lists, or, say, fetch the first three public lists. That would have to be coded manually.

To-Do List Demo

Posted over 7 years back at The Hobo Blog

I’ve posted another demo – this one is a simple to-do list app (see the Demos section). The app took about 10 - 15 minutes to create, which includes figuring out the (minimal!) design.

This demo illustrates a little more of what you can do with the permission system. Each to-do list has a public? attribute. Public lists can be viewed by any visitor to the site, whereas private lists can only be viewed by the owner of the list. Here’s a couple of fragments from the TodoList model that show how we set this up:

class TodoList (fragments)

belongs_to :user
has_many :tasks

def viewable_by?(viewer, field)
  viewer == user or public?
end

Clearly we want this view permission to carry over to the individual tasks in the list. First we define public? and owner methods on the Task model:

class Task (fragments)

belongs_to :todo_list

def owner
  todo_list and todo_list.user
end

def public?
  todo_list and todo_list.public?
end

The owner of a task is the owner of the to-do list it belongs to, and a task is public if it belongs to a list and that list is public. Note that the implementation of these rules is no longer than the descriptions I’m giving in English. Now we can define view permission for the task:

class Task (fragment)

def viewable_by?(viewer, field)
  viewer == owner or public?
end

Run up the demo and have a look at the way these permissions effect the user-interface, as seen by a guest user, a signed in user, and the administrator (to create the administrator, just sign up as “admin”). Are there any holes? You might notice that the front page gets a little out of whack. This is because at the moment there’s no way to count the number of public to-do lists, or, say, fetch the first three public lists. That would have to be coded manually.

Producing Performance Graphs

Posted over 7 years back at RailsExpress.blog

The latest version of railsbench contains scripts to convert raw performance data files into pretty pictures. They depend on rmagick and gruff to be installed on your system.

railsbench perf_plot <files>

will generate a chart comparing benchmark data from all files passed as arguments.

Example:

Enjoy!

railsbench gem version available

Posted over 7 years back at RailsExpress.blog

railsbench is now available as a gem from RubyForge. I recommend all users to switch to the gem version. This move should make it much easier to maintain railsbench installations for a larger number of machines.

Installation is now as simple as sudo gem install railsbench. Or, if you have installed the 0.8.4 gem version: sudo gem update railsbench.

The gem release will install only one ruby driver script, named railsbench in the default ruby path; individual commands like perf_run etc. are accessible through this driver. So instead of typing

perf_run 100 "-bm=all -mysql_session"

you would use

railsbench perf_run 100 "-bm=all -mysql_session"

The perf_ command prefix is now optional, thus

railsbench run 100 "-bm=all -mysql_session"

would give identical results.

If you’re accustomed to the old syntax and find typing railsbench awkward, you could add the gem’s script directory to your search path, by adding the following code to your shell profile:

eval `railsbench path`; export PATH

This will continue to work should you upgrade railsbench to a newer version.

Update: In order to call the scripts directly, you need to issue a sudo railsbench postinstall command after installing the gem. I haven’t found a way to create a gem that sets the executable bit on anything which lives outside the bin directory and isn’t a binary executable.

Singin' Hobo (Not The Stabbin' Kind)

Posted over 7 years back at zerosum dirt(nap) - Home

So it’s the holidays, and I’ve got some time “off” from “work” to recoup and think about my next project, play around with a few ideas, new toys… The first thing on that list of toys is Tom Locke’s Hobo framework.

The Hobo 0.4.0 Gem was released late last week and it’s pretty slick, although we’re warned not to use it in production webapps yet :-). Hobo extends Rails in a number of ways, but the crux of it is that it lets you get up and running with a real, usable (and cleanly coded) Ruby-based webapp quicker than ever before. Hobo bundles in a working user system (acts_as_authenticated), permisisons, and a bunch of other goodies — take a look at the screencast for a quickie walk-through. There also seem to be some interesting ideas here regarding tag libraries, but that’s not covered in this first screencast. Anyway, definitely worth checking out.

Five Things You Don't Know About Me

Posted over 7 years back at Ryan Tomayko's Writings

Bill tagged me. I'm horrible at this kind of stuff but we’ll give it a shot:

  1. I was #38 of 43 in line at this Best Buy from 2:00 AM to 9:00 AM for the Wii launch. I was mildly interested in the Wii but more interested in observing the other idiots standing in line. Conclusion: they’re crazy.
  2. My last name is not Japanese, it’s Czechoslovakian. The original spelling and pronunciation was butchered four generations hence when my great grandfather immigrated to the US.
  3. I have two kids: Lydia Yvonne Tomayko (3Y/Female) and Elijah David Tomayko (2Y/Male).
  4. I went to the same High School as Devo. Are we not men?
  5. When I was a kid, my Dad took me to the memorial at Kent State every year on the anniversary of the shootings.

After about ten minutes of scanning my blogroll, I can’t really find anyone that hasn’t already been tagged so I suppose I’ll be a leaf node.

Release Reflections

Posted over 7 years back at The Hobo Blog

Well it feels great to finally have Hobo out there. We’ve had about 800-900 visits to the site since the launch, 32 downloads of the gem, and who-knows-how-many downloads from the subversion repository because svnserve doesn’t seem to log anything :-)

Oh and around 4.5GB of traffic on the screencast, which is about 360 views assuming everyone downloaded the whole thing (which I’m sure they didn’t!). All of which has cost us a little over a dollar thanks to the incomparable Amazon S3 service. Just awesome.

We had one slip-up in that I completely forgot to mention the dependency on Rails 1.2, so don’t forget to:

gem install rails --source http://gems.rubyonrails.org -y

(and don’t worry when the version it reports back isn’t 1.2)

We’ve had some nice feedback - thanks very much to you all! The one comment I was waiting for turned up on reddit:

It’s the Django admin site/TurboGears Catwalk for Rails?

I’d say no - that would be Streamlined. I was expecting this because we’ve all seen a site pop-up from nowhere with these great tools. What’s different about Hobo is that the resulting site is not just for admins. In fact you can sorta-kinda already see that in the screencast. Thanks to the permission system Hobo is creating different views (with different capabilities) for the guest user, a registered user and “admin”.

But the real eye-opener will hopefully come with the next screencast - where POD will be transformed in no-time-flat into a clean, easy to use, ready to rock-and-roll site. I’m really looking forward to putting that out, but there’s a couple of extra bells and whistles I’m going to attach to Hobo first, just to make the process oh-so-smooth :-)

First up though - I think it’s time for some cheer and merriment. Happy Christmas, Happy Holidays or just Happy Happy - take your pick :-)

Release Reflections

Posted over 7 years back at The Hobo Blog

Well it feels great to finally have Hobo out there. We’ve had about 800-900 visits to the site since the launch, 32 downloads of the gem, and who-knows-how-many downloads from the subversion repository because svnserve doesn’t seem to log anything :-)

Oh and around 4.5GB of traffic on the screencast, which is about 360 views assuming everyone downloaded the whole thing (which I’m sure they didn’t!). All of which has cost us a little over a dollar thanks to the incomparable Amazon S3 service. Just awesome.

We had one slip-up in that I completely forgot to mention the dependency on Rails 1.2, so don’t forget to:

gem install rails --source http://gems.rubyonrails.org -y

(and don’t worry when the version it reports back isn’t 1.2)

We’ve had some nice feedback - thanks very much to you all! The one comment I was waiting for turned up on reddit:

It’s the Django admin site/TurboGears Catwalk for Rails?

I’d say no - that would be Streamlined. I was expecting this because we’ve all seen a site pop-up from nowhere with these great tools. What’s different about Hobo is that the resulting site is not just for admins. In fact you can sorta-kinda already see that in the screencast. Thanks to the permission system Hobo is creating different views (with different capabilities) for the guest user, a registered user and “admin”.

But the real eye-opener will hopefully come with the next screencast - where POD will be transformed in no-time-flat into a clean, easy to use, ready to rock-and-roll site. I’m really looking forward to putting that out, but there’s a couple of extra bells and whistles I’m going to attach to Hobo first, just to make the process oh-so-smooth :-)

First up though - I think it’s time for some cheer and merriment. Happy Christmas, Happy Holidays or just Happy Happy - take your pick :-)

count_on counter_cache

Posted over 7 years back at zerosum dirt(nap) - Home

Counter cache is my new friend. It’s a very important little feature available on ActiveRecord that makes counting associations efficient by maintaining a cache on the model.

Although it’s documented in AWDWR (p359 in my shiny new copy of the second edition), I guess it slipped my mind until now, so I thought I’d blog about it just in case anyone else was looking for a solution…

So why does it rock so hard, you ask? Let’s say that I’m building YADRC (Yet Another Digg/Reddit Clone). I need to count the votes that users make to determine the popularity of an article, display that number, and use it to rank the order of the stories. So we set up our models: a story model, a vote model, and a user model, and we create the appropriate associations. Our vote.rb is going to look something like this:

class Vote < ActiveRecord::Base
  belongs_to :user
  belongs_to :story
end

Predictably, Story has_many votes and User has_many votes. Now we can do something like this to find the number of votes on a story object:

Story.find(4).votes.size

This will work nicely right out of the box. However, once we have a significant amount of stories logged in our system and a reasonable number of votes on each story, performance goes straight to poop. The reason is that each time we’re generating a score for a story (and remember, we’ve got N stories), we’re running a query like this against our database:

SELECT count(*) AS count_all FROM votes WHERE (votes.story_id = 4) 

If we have any real amount of data in our system, this is going to get really ugly. Counter caching is one way to help counteract this problem. Let’s rewrite our model to use it:

class Vote < ActiveRecord::Base
  belongs_to :user
  belongs_to :story, :counter_cache => true
end

We also have to add a column, called votes_count, to the stories table in our database. Make sure to specify a default value of 0 in your DDL. Then we generate a migration, run it, and now we’re ready to try again. The difference should be pretty dramatic. If we tail -f our development log, we’ll notice that those count(*) queries aren’t getting run anymore. So what’s happening?

ActiveRecord is using our counter cache column (called votes_count in this case) on the stories table to store the number of belonging objects on the associate class. This value is incremented when an object of this class is created, and decremented when it’s destroyed. The result is that we have a local “cached count” on the Story instance so we don’t have to constantly query the votes table directly. Good deal, eh?

There are two additional things worth noting about counter caching. As Dave Thomas points out in AWDWR, the counter won’t get updated if entries are added by setting the link to the parent directly in the child like this:

vote = Vote.new
vote.story = story
vote.save

If you’re doing it this way, you’ll have to force the parent class to refresh the collection. The right approach is to add a Vote through the Story object, which makes the parent aware of the increment (or decrement) and update the counter cache accordingly:

story.vote.create

The other point I wanted to make was that if you call the count method on object instead of using size, it will always run the actual count query on the underlying database, instead of using our cached shortcut. Thanks for the tip on that one, technoweenie.

Parallels Makes IE Testing Suck Less, Melts Power Cord

Posted over 7 years back at Ryan Tomayko's Writings

For the most part, the Mac has been an insanely productive environment for web development. The 1GB MacBook Pro stays snappy even when running three or four Ruby VMs loaded with beefy Rails apps, a local PostgreSQL database, many Vims, a couple Terminals, Firefox (with many tabs), The Gimp, and iTunes. I've been spending something on the order of 80 hours/week in this world for some time now and there’s just not a whole lot of pain to report on.

I get a little paranoid when stuff Just Works though so it’s a good thing 99.9% of our customers run Internet Explorer. I'm pretty hard on IE but I will admit to at least one thing it does really well: destroying any sense of pleasantness a developer may feel when building web applications.

We like to test on three different versions of IE:

  1. A fully patched IE 6.0 on a fully patched XP SP2.
  2. The stock IE 6.0 that comes off the original (pre-SP2) XP install media with no patches.
  3. A fully patched IE 7.0 on a fully patched XP SP2.

Of course, you can’t do anything silly like run multiple versions of IE on a single machine. Before IE 7.0, we had two machines (that’s actual physical machines) acting as Terminal Servers for each of the IE 6.0 versions. This sucks for the obvious reasons but adds another soul eating component to the mix: Microsoft’s Remote Desktop Connection for Mac.

  • Slow (still compiled for PPC).
  • Buggy horribly flaky mess of crap hasn’t been updated in years.
  • Cannot start more than one session at a time making it impossible to quickly switch between the IEs.

Once IE 7.0 became a reality, we decided to pony up for Parallels. Unplugging the two Windows boxes instead of adding another one more than paid for the Parallels license but the switch didn’t really solve the productivity problems since you still have to fire up a resource hungry VM for each IE.

IEs Running In The Dock

The latest Parallels beta’s Coherence Mode is trying really hard to bring something of a Mac native feel to Windows apps running under the VM (watch a screencast). Here we have IE 6.0 and IE 7.0 running in the Dock next to Safari and Firefox (kind of grosses you out at first).

You can drag those guys over to make them persistent Dock items. Launching from the Dock will start the VM, enter Coherence Mode, and start a new instance. You can also use QuickSilver:

Quicksilver and the IEs

That’s the good news. The bad news is that after about ten minutes of running with both VMs open, I started to smell burning electronics. The MacBook didn’t seem to be running any hotter than normal and I didn’t see any smoke so I figured maybe it was unrelated. When I went to pack up and go home for the day, I noticed that about ½" of the power cord had melted away, leaving the bare wire exposed!

Melted Power Cord

Taking every precaution, I quickly “fixed” the issue using a pair of paper scissors and black duct tape.

The 85W MagSafe Power Adapter product page has a ton of negative reviews mentioning the “melting thing” and Apple technicians have allegedly said the cause is a hardware issue that causes the laptop to draw too much power. Whatever.

EDIT: apparently, that last paragraph did not do a very good job of relaying my discontent with the melting power cord issue. To be clear: power cords should not melt, even when running beta software. This is clearly an Apple issue.

Tinkering around with the Parallels VM configuration seems to help a bit. I tried to create the lightest VM for running IEs as possible. Here’s a few tips that seem to be helping:

  1. Remove sound, floppy, CD/DVD, and USB from the Parallels configuration.
  2. Under Options / Advanced set the Cache Policy to Mac OS X.
  3. Under Memory, set Main Memory way low (I have mine at 96MB) and adjust the Video Memory to your maximum screen resolution (I have mine at 8MB).
  4. In Windows, disable as many services as possible. Things like Windows Update, the bullshit firewall, sound, the theme engine, etc.

These have not been rigorously tested but everything seems to be running much more smoothly on a 1GB MacBook Pro after an hour or so. Slapping another GB of RAM in here would probably make things a lot smoother as well but I just can’t get over the idea of having to double my RAM just to run a couple of IEs.

All in all, Parallels makes IE suck a bit less on the Mac but this is still a horrible broken mess. What are you guys doing about the IE problem?

Status

Posted over 7 years back at The Hobo Blog

Hobo is currently beta quality. Although Hobo is in active use in production applications, please be aware that if you choose to deploy a Hobo/Rails application on the Internet you do so at your own risk.

Also note that at this stage we reserve the right to make breaking changes to the API.

Current version: 0.8.3

Known Issues

Aspects of Hobo we need to work on:

(of course there’s much more to be worked on than mentioned here – if you come across anything you think should be included in this heads-up, please let us know in the forums)

Active Record Support

Hobo does not currently support has_one and has_and_belongs_to_many. Of course it’s all just Rails so you’re free to use those features in your application, but you will probably run into problems if you try to use Hobo’s various features in conjunction with those kinds of associations. has_one is definitely on the to-do list. has_and_belongs_to_many is not – use has_many :through instead, it’s much better. If you think we’re wrong about this, let us know in the forums! You won’t be the first, but so far we’re sticking to our guns.

DRYML Syntax and Naming

With the 0.6 and 0.7 releases we’ve now done our big cleanup of DRYML syntax and naming. However you can still expect small changes from time to time that will require you to update your apps.

DRYML Performance

Because DRYML promotes a very high level of code re-use in the views, a DRYML page tends to include far more method calls than a typical ERB template. On big pages this can be a significant performance issue.

Tag calls are currently slower than they need to be because at this stage we’re optimising for code clarity rather than performance. At some point we will start tuning this code to run faster, or…

Status

Posted over 7 years back at The Hobo Blog

Hobo is currently beta quality. Although Hobo is in active use in production applications, please be aware that if you choose to deploy a Hobo/Rails application on the Internet you do so at your own risk.

Also note that at this stage we reserve the right to make breaking changes to the API.

Current version: 0.8.3

Known Issues

Aspects of Hobo we need to work on:

(of course there’s much more to be worked on than mentioned here – if you come across anything you think should be included in this heads-up, please let us know in the forums)

Active Record Support

Hobo does not currently support has_one and has_and_belongs_to_many. Of course it’s all just Rails so you’re free to use those features in your application, but you will probably run into problems if you try to use Hobo’s various features in conjunction with those kinds of associations. has_one is definitely on the to-do list. has_and_belongs_to_many is not – use has_many :through instead, it’s much better. If you think we’re wrong about this, let us know in the forums! You won’t be the first, but so far we’re sticking to our guns.

DRYML Syntax and Naming

With the 0.6 and 0.7 releases we’ve now done our big cleanup of DRYML syntax and naming. However you can still expect small changes from time to time that will require you to update your apps.

DRYML Performance

Because DRYML promotes a very high level of code re-use in the views, a DRYML page tends to include far more method calls than a typical ERB template. On big pages this can be a significant performance issue.

Tag calls are currently slower than they need to be because at this stage we’re optimising for code clarity rather than performance. At some point we will start tuning this code to run faster, or…

Demos

Posted over 7 years back at The Hobo Blog

Download complete Hobo demo applications, and watch them being created in the screencasts. All the demos require Rails 1.2

The demos are standard Rails apps. To run them

  • Download and unpack the demo archive

  • Create the database, e.g.

    $ mysqladmin create pod_development

    (look in config/database.yml for the name of the database you need to create)

  • To create the required tables, open a terminal in the demo’s main directory, and:

    $ rake db:migrate

  • Run the development server

    $ ruby script/server

  • Point your browser at http://localhost:3000

POD Demo

POD is a simple classified advertising application, created using Hobo and Rails in just five minutes.

* You can watch the the development of POD via the screencasts page

Downloads:

* Pod Demo - Introduction to Hobo: zip * Pod Demo - Page Customisation: zip * Pod Demo - Replacing the Theme: zip

(Note that the third demo (stylevantage) is massively incomplete and broken in many places. It is included just for information purposes)

To-Do List Demo

No screencast, but some discussion of the permissions in this post

* Download ToDo: zip

Demos

Posted over 7 years back at The Hobo Blog

Download complete Hobo demo applications, and watch them being created in the screencasts. All the demos require Rails 1.2

The demos are standard Rails apps. To run them

  • Download and unpack the demo archive

  • Create the database, e.g.

    $ mysqladmin create pod_development

    (look in config/database.yml for the name of the database you need to create)

  • To create the required tables, open a terminal in the demo’s main directory, and:

    $ rake db:migrate

  • Run the development server

    $ ruby script/server

  • Point your browser at http://localhost:3000

POD Demo

POD is a simple classified advertising application, created using Hobo and Rails in just five minutes.

* You can watch the the development of POD via the screencasts page

Downloads:

* Pod Demo - Introduction to Hobo: zip * Pod Demo - Page Customisation: zip * Pod Demo - Replacing the Theme: zip

(Note that the third demo (stylevantage) is massively incomplete and broken in many places. It is included just for information purposes)

To-Do List Demo

No screencast, but some discussion of the permissions in this post

* Download ToDo: zip