watch this  

the official mrchucho blog

Still Learning, Part Two

Posted 2007 Feb 01

So the problem I wrote about in Part One involved passing the organization_id of the current_user into just about every Model method. I quickly set off looking for the most complex solution: filters, overriding the base find_ methods, meta-programming, monkey-patching, you name it!

Well, too bad the answer was staring me right in the face: make the calls to each model relative to the current_user! There’s a reason :has_one, :has_many and :belongs_to exist!

So, instead of writing:


Attendance.find_by_organization_id_and_room(
    current_user.organization_id, room)

I should write:


current_user.organization.attendances.find_by_room(room)

Now, that doesn’t seem like a big difference, but it saves me from having either add a “by_organization_id_and” to every find method or adding some “with_organization_scope” code. It also feels more like Rails.

I have one concern, though. The call to “current_user.organization.” will result in a database call versus just passing “current_user.organization_id”. While this doesn’t seem like a big deal, it seems a little unnecessary. Since the current user’s organization won’t change—I should be able to cache it.

Update: /sigh. I shoulda known. This was covered on a recent Rails Way post.

comments (0)

Still Learning, Part One

Posted 2007 Feb 01

Recently, I was struggling with part of my Rails application. Feeling I was missing the point, I sent this submission to The Rails Way.

In a nutshell, I have a attendance management system that can support many different organizations ( e.g. schools, churches, etc.). All facets of the attendance management system are “tied” to a particular organization such that a user in a given organization can only create, edit or view data with a matching organization_id. I think you can guess my problem now…

I end up having to pass the current user’s “organization_id” around EVERYWHERE. I’ve been able to DRY to a certain degree using with_scope:


class User < ActiveRecord::Base
  belongs_to :organization
end

class Attendance < ActiveRecord::Basee
  belongs_to :organization

  # current_user is an instance of User, passed in by the controller
  def Attendance.find_todays_attendance(current_user)
    Attendance.with_organization_scope(current_user.organization_id) do
      find(:all, :conditions => ['attendance_recorded_on = ?', Date.today])
    end
  end

  def Attendance.with_organization_scope(org_id)
    with_scope(:find => {:conditions => ["attendances.organization_id = ?", org_id]}) do
      yield
    end
  end
end

And so on. But I still have to add current_user or organization_id as a parameter to just about every method call. And the biggest problem is that it fails “silently” – i.e. if you forget to check the organization_id you could expose another organization’s private data.

Check back for Part Two where I think I’ve finally seen the light.

comments (0)

My Rails Way

Posted 2007 Jan 26

Inspired by my new favorite Rails site, The Rails Way, I’m posting a little Rails refactoring I did recently.

In a nutshell, a different CSS class needs to be applied to a row depending on birthday. Otherwise, use standard Zebra rows (via even_odd helper). Previously, the code looked like this:


def even_odd_or_birthday(birthdate)
  if birthdate == nil
    @alternate_odd_even_state = even_odd ? 'even' : 'odd'
  elsif birthdate.yday == Date.today.yday
    @alternate_odd_even_state = 'birthday_today'
  elsif (birthdate.yday >= (Date.today.yday - 7) && birthdate.yday < Date.today.yday)
    @alternate_odd_even_state = 'birthday_past'
  elsif (birthdate.yday <= (Date.today.yday + 7) && birthdate.yday > Date.today.yday)
    @alternate_odd_even_state = 'birthday_future'
  else
    @alternate_odd_even_state = even_odd ? 'even' : 'odd'
  end
end

Besides being incorrect, it seemed cumbersome and not very Ruby-like. Note that the granularity required is only a day, not time. Next is what I’ve come up with instead:


def even_odd_or_birthday(birthdate)
  return even_odd if birthdate.nil?
  today = Date.today.yday
  case birthdate.yday
  when today
    'birthday_today'
  when (today - 7) .. today
    'birthday_past'
  when today .. (today + 7)
    'birthday_future'
  else
    even_odd
  end
end

Though it isn’t any shorter, it reads a more naturally to me. Any improvements or suggestions?

comments (0)

Syntax Highlight Plugin Test

Posted 2007 Jan 26

This is a test of the awesome syntax highlighter:


7.times do
  puts 'Hooray' if true
end

I hope that works.

comments (0)

Growl Plugin available at official Mozilla Addons site

Posted 2007 Jan 15

My growl plugin is now available from the official Mozilla Addons site. It can be found here.

comments (1)

Rails Way

Posted 2007 Jan 11

I think that Jamis Buck and Michael Koziarski’s The Rails Way might be the most important Rails website I’ve found to-date. Their “peer reviews” of Ruby/Rails code are top-notch. As mentioned in the comments, “The Rails Way” is great Rails consulting… for free!

In their latest review, “The Rails Way” addresses the common abuse of the id property. After reading the article, I examined some of my code and found that I was making the same mistake pretty regularly.

On many occasions I was writing:


Attendance.find(:all,:conditions => ["attendances.person_id = ?", person.id])
when I really should be using:

person.attendances.find(:all)
Clearly, this is a “forest for the trees” issue :P

comments (0)

Impressed Again

Posted 2006 Dec 12

I’ve been working on a big Rails project and I’m still finding things that impress me. Recently, I wanted the equivalent of SQL’s “IN” statement, e.g.


select *
from people
where first_name in ('MrChucho','MsChucho')
I wasn’t immediately sure how to do this with Active Record, so I tried what seemed most intuitive: passing an Array to find…

Person.find_by_first_name(['MrChucho','MsChucho'])
It worked perfectly!

comments (1)

Chucho MUD: Now dependency-free!

Posted 2006 Nov 11

I’ve updated Chucho MUD to remove the dependency on Teensy MUD. I doubt my network code is as robust, but I’m glad to be rid of the dependency. Still, I owe Teensy MUD a lot for inspiration!

Also, I’ve started adding preliminary ERB support for descriptions (and, eventually, all output). Using ERB has even allowed some “markup”, e.g.


You see a < % red do %>red< % end %> flag.
All ERB parsing occurs in the Reporter—right before it’s sent to the client. Another example:

desc = %{\\
You are in the < %=room.name%>. You see < %= room.items.join(', ') %>. 
}
I’ll be adding more (consistent) support soon.

comments (1)

SOA is...

Posted 2006 Nov 07

As someone who is constantly subjected to the SOA gospel, SOA Facts made my year.

J2EE can sometimes make a diamond from a lump of coal. SOA can make diamonds from air.

I’m trying to decide between posting a copy on the wall outside my cube or “accidentally” leaving it on the printer trays on my floor…

comments (0)

Chucho MUD Hosted

Posted 2006 Nov 03

I’ve setup a Google Code project for Chucho MUD, complete with a Subversion Repository and Issue Tracker.

You can grab the latest version:

svn checkout http://chuchomud.googlecode.com/svn/trunk/ chuchomud

There’s still a dependency on Teensy MUD for the networking core, but that project seems to have disappeared… But you can grab the latest version (2.10.0) via MUD Magic and stick it under vendor.

I’ve reworked a lot of the code and added some unit tests. There is still a lot unfinished, but it’ll run. There’s a “test” game database under test/game.

comments (0)
atom rss