Half-Penny For Your Thoughts

rounded down to the nearest cent



Categories


Recent Articles




GraffitiWok.com

Roles and Permissions on GraffitiWok

So, I didn’t user merb-auth for GraffitiWok, partly because it wasn’t when I started. But, actually, the users and roles was one of the more complicated and app-specific parts to GraffitiWok, so I probably would have gone the full custom route anyway.

The particularly interesting part (to me) where Board and Note specific permissions, based on two criteria: ownership of the object (an owner can do anything to that object or to its Notes if the object is a Board) and general permissions for all logged-in or guest users. Actually, the models are built to allow per-user permissions, but its not really implemented.

So, there are actually six relevant models, which I’ll review briefly:

  1. User - The basic model for users
  2. GuestUser - A singleton class representing an anonymous user. I’ll actually ignore this in the subsequent discussion
  3. Role - A role, which just records a name and id. For example, “editor” or “poster”
  4. UserRole - An intermediate model connecting a Role, a User, and a Board. That is, it says “Bob (User) is an ‘editor’ (Role) on Board #1”
  5. Permission - A name and id identifying a permission
  6. RolePermission - An intermediate model connecting a Role with its many permissions.

So, a User has one or more Roles for a given Board (or, uses the default roles) each of which then have a set of permissions, thus, per board, a User has a given set of permissions. The upshot of this is some meta-programming to have code like User.first(:email => ‘bob@example.com’).can_edit?(Note.get(1)). I like it, anyway.

Here’s the interesting code:

def process_permission(permission, obj)   
  if obj.kind_of?(Note)
    board = obj.board
    permission += '_note'
  else
    board = obj
  end
  
  if p = Permission.first(:name => permission)
    return true if (obj.owner == self && permission != 'create_note')
    return true if (permission == 'create_note' && obj.board && obj.board.owner == self)
    ur = UserRole.all(:board_id => board.id, :user_id => self.id)
    ur = UserRole.all(:board_id => board.id, :user_id => -1) if ur.empty?
    return ur.collect{ |r| r.role.permissions}.flatten.include?(p)
  end
  
  return false
end

def method_missing(sym, *args)
  if sym.to_s =~ /\Acan_([\w_]+)\?\Z/
    return process_permission($1, args.first)
  end
  super
end

def respond_to?(sym, *args)
  # repond_to can_{permission}? methods if there is a permission with the
  # given name.
  return true if super

  if sym.to_s =~ /\Acan_([\w_]+)\?\Z/
    return (Permission.first(:name => $1) || 
      Permission.first(:name => $1 + "_note") ?
      true : false)
  end

  return false
end

The process_permission method is where the real work goes on. If the object is a Note, it actually checks for a permission with the suffix _note on the given Board (with some special coding for can_create_note?). It also uses the default Roles (those for the Board where the User id is -1) if that User has no assigned roles for this Board (a similar thing happens with GuestUser).

For GraffitiWok, I think this approach has worked rather well.


GraffitiWok.com

Using Git

So, I decided to try out git) while developing GraffitiWok instead of Subversion which I normally use for version control. I’ve been quite please with Subversion and have found uses for it beyond just versioning software development (see Wistle), but I’d started hearing a lot about git at about the same point I started working on GraffitiWok.

First and foremost, the people who still claim you can’t use git on Windows are apparently nuts. I have been doing so for nearly a year using this download. So, what have been my impressions.

I love the ability to easily add only a part of the changes in a file to a commit. I realize that running into the need to do this reveals an occassional lack of planning on my part, but it’s really nice. I also really like the ability to amend the last commit. This has come in handy several times as well.

What I haven’t really tried is the branching and merging. Most of the projects I’ve used version control for have been my own; I’ve never programmed on a team. Still, even without that, git is at least as good as Subversion. Or, that is to say, on a one person team, I’m not sure there’s a particular difference.


GraffitiWok.com

jQuery and GraffitiWok

So, GraffitiWok is heavy on the javascript, heavy on the ajax-y goodness, etc. I started out using Prototype. Actually, Prototype worked pretty well, but I became frustrated with it. It does so much that it was making it difficult to get my own custom code going. So, I tried mootools, but that ended up causing some weird problem slowing down everything. I gave up and went back to prototype.

Later, I started needing to do some remote form submittal. Rails has helpers to generate the code Prototype needs, but it’s pretty nasty code if you don’t have the helpers. And I didn’t feel like writing them. That’s when I found this slide show, which shows some advantages of using jquery. Particularly, it’s easy to use without all those Rails helpers (Prototype is a bit too Rails-centric, in my opinion). For a js-heavy app, I wanted to have that control to not need to rely on helpers in my views that I didn’t understand.

So, I started with jquery, and the excellent array of available plugins. I have no intention of using prototype again. Jquery may not be the best js library out there (and no doubt which is best depends on the usage), but I find it much easier to use than prototype.

I did miss one thing with prototype, which was it’s “class” structures that look and feel more like Ruby than the typical javascript class structure. But, then, Prototype messing with javascript at all sorts of levels was one of the things that got on my nerves, so I was in some ways glad jquery does build in that kind of thing. Instead I went searching for a separate library.

This base.js script does the trick nicely, and it’s a separate piece that I can add in to a project or not, instead of one monolithic library that just does too much. Combined with jquery and a few choice plugins, it saved me a lot of time on the javascript for GraffitiWok.


GraffitiWok.com

Built with Merb and DataMapper

So, GraffitiWok was my first adventure using Merb and DataMapper after a fair amount of Rails experience. Although, I stopped fairly near the beginning to work on my blog app, Wistle which also benefits from these great libraries. Some thoughts about using them.

Merb

I’m excited about the forthcoming merging of Merb and Rails, because I really like Merb, but it doesn’t have all the toys Rails has. Part of that’s good, because I don’t always want even most of the Rails stuff. As I understand, the merging will include Rails having Merb’s ability to specifically load various parts of the framework (and different ORMs, testing libraries, etc). The ability to have more control over dependencies is really nice, even when I’m not concerned about memory: I just like having a better idea of what all I’m loading with the app. For GraffitiWok, there wasn’t a whole lot I needed.

I did start using haml more than erb. Haml is great, although I’m still more comfortable in ERB. I guess that’s mostly personal preference.

The display method (roughly similar to Rails’ render method) is one of my favorite features of Merb and something I use consisently in the GraffitiWok code. It’s just easier to use. I also really like that what’s rendered can just be a string returned from the action method. Much more simple and logical, at least to me.

DataMapper

There are occassions when I just don’t get DataMapper. Like how do I order a query by random(). Seriously. Anyway, the models in GraffitiWok were pretty simple, except maybe the user stuff. I really like listing the properties in the models. Anyway, for the most part I’m more than willing to say goodbye to active record. I can’t think of any particularly telling example, but DataMapper just makes more sense to me. I guess it’s the feeling that there’s less crazy magic going on.


GraffitiWok.com

GraffitiWok.com

Well, I have another little fun web app up and running. Check it out at GraffitiWok.com. Aside from the chance to advertise a site from which I don’t expect to ever profit, I thought I’d share a bit about developing it, with this article as an intro and then some additional discussion in later articles.

The Idea

The concept is that off post-it type notes on a board of no particular size limit. Actually, the real concept was a web site that acted as a wall on which people could draw, but alas. Features I’ve considered and may not get around to are the ability to add pictures and videos to this “wall” or “board” as I’ve ended up calling it in the code. Actually, I think it turned out kind of neat. It’s just that it doesn’t actually meet any need that I can think of. Oh, well, it was fun.

The Technology

GraffitiWok introduced me to several technologies: Merb, a Ruby web framework soon to be integrated with Rails, DataMapper, a Ruby ORM, similar in theory to ActiveRecord, although rather different in practice, jquery, a javascript library, and the version control software git. For those who follow this blog, you’ll figure out that this project has been a long time in process, about a year with seeds before then, as Wistle uses Merb and DataMapper; GraffitiWok actually proceeded Wistle.

Anyway.

It was a fun way to learn about these technologies and that’s what the follow up articles will be about.

Developed for Firefox

Yes, it works in IE. It might even work in Safari and Opera (I haven’t tried), but I really developed this to work in Firefox. Why? Because I could. After all, it was primarily for fun, not money, and I didn’t feel like worrying about browser incompabilities. Although, thanks to jquery, those are probably minimal. Still, it was really nice not spending a great deal of time jumping between browsers–especially since IE became very slow with it at several points.