
A few of the attendees looking over the topics board to
pick out which sessions they're going to go to.

GateKeeper is a Ruby on Rails plugin providing a natural language DSL to manage security permissions on instances of ActiveRecord classes at the Model level. Permissions may be assigned based on the current users roles, and/or by their relationships to the object in question. GateKeeper automatically intercepts all attempts to CRUD (Create, Read, Update & Destroy) instances of ActiveRecord classes and verifies the current user has permission before allowing the operation to proceed.
The main requirement of GateKeeper is that it expects that you have a 'User' class, and that it responds to the class method 'current', as in 'User.current'. If you need to use a different class (such as 'Person' or something), that can be defined in your environment.rb, but whatever it's called, it must respond to 'current' and return an object that represents the currently logged in user. So, here's a simple example of how to set that up.
Exactly how you get your users logged in is up to you and still beyond the scope of this post, but I'd recommend a SessionsController and a User.login(username, password) method. So, we'll assume that you have that setup already and that you store the 'id' of the currently logged in user in session, such as 'session[:user_id]'.
The first thing you'll want to do is have a method in your application controller that sets up the current user for the rest of the application...
class ApplicationController < ActionController::Base
before_filter :setup_user
def setup_user
User.current = User.find(session[:user_id])
end
end
Now, we need to add 'current' and 'current=' methods to User.
class User < ActiveRecord::Base
## Class Methods ##
class << self
def current
@CURRENT_USER || User.new(:username => 'guest')
end
def current=(u)
@CURRENT_USER = u
end
end
end
And that's it for User.current. Now, anywhere in your application (Models, Controllers, Helpers, and Views), you can just call User.current, and get an object that represents the currently logged in user. Now we'll go into some basic uses of GateKeeper.
If users can register new accounts on your site, then you'll need to allow 'guest' users permission to create new users. Update your User class with the following (previously shown class methods left out for brevity).
class User < ActiveRecord::Base
## Permissions ##
creatable_by_guest
#################
def is_guest?
username == 'guest'
end
end
However, if at any point your application tries to save the current user, it could potentially end up creating a user with the username 'guest', which you probably don't want. So, update the above with the following...
## Permissions ##
creatable_by_guest :unless => lambda {|new_user| new_user.is_guest? }
#################
The 'is_guest?' method above is an example of how to define dynamic 'user roles' for GateKeeper. When you say 'creatable_by_guest', GateKeeper expects to either find a 'is_guest?' instance method on User, or a Role named 'guest' belonging to User.current (see below). Here are some examples of other dynamic user roles that you might want to define for your users.
class User < ActiveRecord::Base
def is_premium_member?
premium_membership_expires_on > Time.now
end
def is_logged_in_user?
!is_guest?
end
def is_popular_user?
popularity_ratings.size > 42
end
end
class Foo < ActiveRecord::Base
## Permissions ##
creatable_by_premium_member
updatable_by_popular_user
readable_by_logged_in_user
#################
end
As I stated above, GateKeeper also looks for a Role belonging to User.current with the name of the Role used in the permission. To set this up, you'll want the following...
class CreateRoles < ActiveRecord::Migration
def self.up
create_table :roles do |t|
t.string :name
t.timestamps
end
add_index :roles, :name
create_table :roles_users, :id => false do |t|
t.integer :user_id
t.integer :role_id
end
add_index :roles_users, :user_id
end
def self.down
drop_table :roles
drop_table :roles_users
end
end
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
Now, if you were to create a role named 'moderator', and assign it to a few of your users, you could give those users special permissions on certain models, such as updatable_by_moderator . Take note that the role name should be all lower case and underscored so that your permissions look nice. If you have a role named 'SpecialUser', then your permissions would need look like 'readable_by_SpecialUser' which isn't beautiful code, and if the role name has spaces in it, it won't work with GateKeeper at all. 'special_user' is a much more appropriate role name for GateKeeper's purposes.
So, there you have it. I hope that helps some people get over the initial hurdle of setting up GateKeeper. I'd love to hear from anyone using GateKeeper and hear your thoughts and questions.
You know that flatulence like sound that balloons make when you let the air out and the last bit finally escapes before it goes completely limp? That's the sound that Ben Stein's career is making right now. But if you still feel compelled to go see this garbage, here's one more site about --> Expelled <-- that you should read first (created by the National Center for Science Education), and be sure that you offset your price of admission with a truth ticket or two... or three... dozen.
ARID ( ActiveResourceIntegrationDsl ) is a Ruby on Rails plugin offering easy to use methods for writing integration tests on RESTful Rails apps. With ARID you write simple statements like user.builds_article(:params => {:article => {:subject => 'Hey!', :content => 'Hello World!'}}) which will GET your new_article_path, check that it has a properly formatted form with fields for all the given params, and then will POST the params to articles_path and assert the expected response. You can even pass a block to the above call to perform additional tests. And YES, ARID tests AJAX calls.
More info and installation instructions at http://arid.rubyforge.org.
Cross Site Sniper is a Ruby on Rails plugin that automatically html escapes all string and text fields of ActiveRecord objects. Data is escaped as it is retrieved from the database to protect your site from XSS (cross site scripting) attacks without modifying or corrupting your original data. Convenience methods are provided to access the unescaped data when necessary. Edit forms are prepopulated with unescaped data as well to avoid user confusion and prevent double escaping.
Documentation and install instructions can be found at http://xss.rubyforge.org.
And I'm going to stay this way all day long! In honor of "CSS Naked Day", 5Valleys is going to spend the day lounging around the web in the nude.
I don't consider myself anything remotely close to a designer. My aesthetic eye is completely non-existent (anybody who's seen me try to dress myself knows this). Which is why, once I grasped an understanding of the full power of CSS and learned how to set up a CSS friendly site, I came to really appreciate CSS. This way, I can turn over the beautification of the site (not this one specifically, this crap is all my doing) to a talented designer who can just work some CSS magic and make it all pretty.
Therefore, to help draw attention to CSS and promote web standards, 5Valleys is joining hundreds (thousands?) of other websites around the web, and turning off it's CSS for the day. See who's all playing along at the CSS Naked Day page. My apologies to those who followed a link here hoping to see a picture of me with my Johnson swinging in the breeze. Maybe next year.
Anyway, we managed to get some really good seats, and I managed to get almost the entire speech on video, which I'm now trying to get uploaded to youtube in 5 parts. The links to each are below (or will be once I get them all uploaded.) My camera's memory card decided that it had had enough politics for one day just seconds before the end of the speech, so that's where my footage ends. He was just wrapping up at that point though, so nothing of substance was missed.
As recently as just a couple years ago, I didn't "get" RSS feeds. I understood the general concept, but I didn't understand WHY. What's the point? Why all the hubub?
Now, two years later, I can't believe that some sites STILL don't provide RSS feeds. Case in point... the Missoulian. This is a website for a newspaper! They have updates every day, but I really don't want to have to remember to go check their website every day (which I don't and that's why I rarely go there) and I don't want to have to wade through a bunch of garbage on the site to see what's new. I just want a simple list of headlines to automatically show up on my computer as they become available, and I want to be able to click any that interest me to go right to the full story at the Missoulian. This is the 21st Century. This is how news gets distributed now. Everybody from The New York Times to I Can Has Cheezburger? have RSS feeds now, but the Missoulian? Noooooo... well, until now. But not becuase they did anything about it.
I finally got fed up with not being able to keep up on the local news as easily as I could on the national and international news. So, I wrote a little Ruby script to figure out what the latest stories and breaking news was at the Missoulians website, and format it into a couple RSS feeds. And, because (as I've said before), "you're all that, and more," I'm giving it to you, too.
One word of warning, though. The underlying HTML at the Missoulian has the consistency and structure of potato salad, making it very difficult to programatically figure out where the news stories are inside the mess, and therefore any little change they make to their site could easily break the feed. Considering they should be seriously thinking about redesigning their site anyway, it's only a matter of time before this happens. Or, maybe not... who knows. Anyway, if the feed breaks, I'll see about fixing it as soon as I damn well feel like it... until they start paying me for the service.
So, without further ado, here's the links for the feeds. Copy and paste the URLs into your favorite feed reader. And post a comment here to let me know how you like them.
Another thing that I didn't really "get" until recently were Podcasts. Podcasts are like RSS feeds (in fact, they are RSS feeds), but instead of delivering text and a link off to some news site or blog, they provide a link to an mp3 file that your computer automatically downloads for you. When people hear mp3 they often think "music" but podcasts are usually just people talking, and the first ones I ever tried to listen to were people who really, really liked to hear themselves talk and who didn't say anything I was particularly interested in listening to. Which is why I didn't "get" it. "Why the hell do people want to listen to this crap?" I asked myself. A great many (maybe even most) are still like that. But I've come to realize that hidden among all the garbage are a few really, really good gems. Podcasts get their name from iPods, but you do NOT need an iPod to subscribe or listen to them. Any podcast client (google for it) that you can install on your computer will do, although having a convienent way to move them onto an mp3 player to so you can listen to them, for instance, while driving to work, mowing the lawn, and so on is extra nice. It's kinda like TIVO for internet talk radio.
So, anyway. While working on the above RSS feeds, I had an idea. KUFM, the local Public Radio station posts the evening news as an mp3 file on their site, but it's not a podcast. While I'm doing these RSS feeds for the Missoulian, why don't I turn that news into a podcast for KUFM? Then I can listen to the previous nights news while on my bike on my way to work the next morning! So... I did that too, and again, since you're all that, and more.... (note: they seem to be having some audio issues with the last couple episodes, but my tests for last weeks shows worked fine, so as soon as they solve that, this should work great.)
And to close things off, Here's a short list of some of my absolute favorite podcasts. Load your mp3 player up with these, and like me, you may never want to turn your TV on again.
Obama and BarCamp are coming to Missoula. Thankfully, not on the same day.
Thanks to my new Missoulian RSS Feed (what? huh? move along, nothing to see here... next post on that subject) I just found out that Presidential Candidate Barack Obama is having a free rally at the Adams Center Saturday morning. I'd be there even if it was Bush III, I mean John McCain. This is history in the making folks!
And on a completely unrelated note, Missoula is having it's own BarCamp on April 26th (also a Saturday). What's a BarCamp? According to Wikipedia....
The official site for Missoula's contribution is at http://missoulabarcamp.org. Registration is required. Early registration recommended. I hope to see a great turnout of Missoula's Tech Professionals.