This one's going to be a big one, be prepared for reading it in parts.

Base Auth's readme is of course available on its GitHub page, so make sure you have it open for reference.

Read the rest of this entry

Base Auth grown up to 0.2

December 5th, 2008

A long, long time ago (a year in Rails world is almost a geological period) Robzon has published and announced Base Auth, his first serious Rails plugin. "Base" actually stands for "Best Authorization System Ever" and while it's of course tongue-in-cheek, simplicity and power of this plugin are sometimes simply stunning. We've been using it in most of our projects here and not only because Robzon is one of the founders and bosses ;)

I didn't like some of the approach that Base Auth forced on programmer, namely putting everything in filter and throwing the whole burden of authorization on controller's back. I want to keep my controllers thin and put as much as possible into the model, goddamit! For a few weeks now I've been trying to convince Robzon to add model-based authorization to Base Auth, preferably using as much common code with already implemented controller-based authorization as possible. After some perseverance I finally heard "YOU can implement it, especially since we moved base_auth to Github" and after getting such green light there wasn't much more to do than just sit and implement what I wanted to see there.

So there it is: Base Auth 0.2, available on GitHub, has now a pretty simple yet powerful and extensible support for model-based authorization. Just install, check and define Model#authorize (if default implementation doesn't suit you) and use model-based authorization this way:

Class ItemsController < ApplicationController
  def edit
    @item = Item.find(params[:id]).authorize!(current_user)
  end
end

Of course it's just the tip of an iceberg, as there's the whole world of controller-based and views-usable authorization methods available in Base Auth, of course compatible and interchangeable with the model-based one. Read the README and wait for a full tutorial here.

One last thing: you should gracefully rescue from exception thrown when authorization fails:

Class ApplicationController
  rescue_from Authorization::PermissionDenied, :with => :permission_denied
  
  def permission_denied
    render :text => "You don't have the permissions for this", :status => 403, :layout => true
  end
end

Same of course applies if you use allow! and deny! with controller-based authorization. Anyway, a bigger Base Auth tutorial is about to follow. Stay tuned!

Sticking up with the Engines theme and "stuff that many of our clients want in their applications", there's one small plugin we did some time ago in cooperation with developers from outside the company. We all needed a pluggable newsletter engine that would be easy to install, maintain and upgrade.

That's when NARN was created. It's a pretty small, but very useful Rails Engines plugin. It's on GitHub of course, so feel free to grab, test, modify and send suggestions and patches. You know you'll need a newsletter in some of your apps one day ;)

There's been a lot of talk about Rails applications not being modular-able, forcing developers to copy-paste code instead of plugging it in in a true DRY spirit. Despite these claims, some developers believed they can make RoR apps modular and created Engines, one of the best and most innovative Rails plugins ever.

Most web applications come today with some ways to socially interact with other users. I believe they call it Web 2.0, although I saw this term used to label to many, many different things, including AJAX and standards compliant HTML and CSS. Anyway, there are a few means of such social interaction, including commenting (any or most of users' content), wikis and - my personal favourite - forums.

To the point. First there was Beast, an attempt to do functional RoR forum in 500 lines of code. Then came Rails 2.0 and together with it William B. Harding wrote Savage Beast, a RoR 2.0 compliant Beast fork. It's great (thanks, William!), but the code wasn't perfect: it didn't work properly with Rails 2.1, used outdated will_paginate (everyone's using Mislav Will_Paginate currently, right?). We needed a working Rails forum solution, preferably pluggable (so we could reuse the code given to our clients and let them upgrade forum engine painlessly), so we've forked Savage Beast, corrected a few imperfections, called it Aep Beast and put it on GitHub.

The best thing about GitHub in specific and Open Source in general is that anyone can grab the code, use it, fork it / modify it and make Aep Beast even better, cleaner, leaner and easier to use. So, everyone - feel free. GitHub awaits :)

If you have any suggestions, put it in the comments. Or, especially if you have a patch, mail me.

PS. What's the origin of "Aep" before the "Beast"? Well, it was supposed to be a part of "Aenima Platform", sort of RoR application scaffold and set of plugins we were going to reuse in many of the applications. But this idea got scraped when awesome Rails Generator came by. Now "Aep" means "from, coming from, derived from", from the Elder Speech - a language created by Andrzej Sapkowski in his books about the Witcher. We're (most of us) fantasy geeks anyway here. And if you haven't read his books about the Witcher, it's right about time.

Suppose you'd like to have some "static" (as in html.erb, without content in the DB) pages on your Rails site. And to have some nice path, like mydomain.com/articles/somearticle, pointing to a file somearticle.html.erb somewhere in your app directory.

Well, this is the simplest and probably nicest of the options (and it's very "Ruby Way"). But I have to test it a bit more to clear some security questions - use at your own risk.

class ArticlesController < ApplicationController
  def method_missing(name)
    path = "#{RAILS_ROOT}/public/articles/#{name}.html.erb"
    render :file => path, :layout => true
  end
end

The best thing about it? 100% Globalize compatible, i.e. Globalize will automatically try to prepend extension with two-letter language code as usual with view files.

Sunday started pretty funny actually (wasn't so funny back then) - we forgot about daylight saving one-hour switch and after finally getting up we've realized that we don't have over 90 minutes until my talk, but only half an hour. We rushed into the Charles University with me leading, as getting late on one's first conference talk ever is definitely a bad idea. I managed to get on time, mostly thanks to my predecessor stretching his talk a bit and coffee break. After some fighting with xrandr (thanks Karel!) I was ready to go. Well, at least technically.

11.30: Tomasz Stachewicz - "Sharing the load". It's not a good idea to write about my own talk. Let's just say it went well I think, put some light onto OpenWFEru (which I wanted to do the most) and showed that BackgrounDrb isn't the only way to go.

After doing some lunch break (and first beer that day) we were back at Euruko, to listen to some more talks.

14.30: Tim Becker - "Lessons Learned Writing Native Extensions". A good one. Not a lot of jokes, but very decent from technical standpoint and definitely worth the time. Could start from some higher level (as in "higher than explaining C types"), but for some this revision of basics was very refreshing and it's always better to start explaining from too low than from too high level. Tim Becker is on my Ruby radar - I think he's going to write some good stuff.

15.00: Matt Ford - "Aspect Oriented Programming in Ruby". I always wanted to learn a bit about AOP in Ruby and this walk was just what I needed. Enough said :)

After some more lightning talks we had to rush to train station. I've just managed to tell Karel and Peter that it was a perfect conference (exactly - perfect: I wouldn't like to improve anything) and we'd like to organize Euruko 2009 or 2010 in Poland, in Krakow to be precise.

First week of june seems like a perfect time to write about EuRuKo, a conference held at the end of march. Well, sarcasm aside – starting a company/group technical blog (and by starting I mean “populating with content”) isn’t the easiest thing we’ve been doing.

Disclaimer: this one is written by me (Tomash) and presents only my personal perspective. I’m trying to talk other guys into writing their own impressions.

Enough babbling, time to start with the report.

Saturday.

It was a good morning. Well, a decent at least, considering some partying after reaching Prague on friday. After breakfast, registration and letting our girlfriends visit Prague on their own we were ready for our first Ruby conference. As we all know from EuRuKo Program, it all started with Matz.

10.00: Yukihiro “Matz” Matsumoto – “Keynote”. This one was great, definitely one of the best talks during this Euruko. Not (only) because it was Matz who gave it, but mostly because it perfectly balanced some technical details and jokes. Matz turned out to be a pretty good English speaker (definitely better that what I’d expect from Japanese), at least comparing to Koichi that was about to follow…

11.00: Koichi Sasada – “Ruby meets VM”. Now, Koichi is a great man and he deserves a lot of respect for task as daunting as writing VM for Ruby. His talk was great from a technical point of view. At least from what I understood. And there we are, at the weakest point of his talk—some slides were in japanese and Koichi is simply… well, let’s say that he’s definitely better at Ruby than speaking english ;)

Because we actually knew JRuby, we’ve decided to have a walk through Prague Old City (it’s beautiful) and try some more of famous Czech beer. Being Polish we’re actually a bit picky about beer from other countries, but the beer we drank in Prague was – regardless of brand – just great and, I dare say that, even better than beer in Poland.

After getting back and having some great lunch at the conference we were prepared for next set of talks.

14.30: David A. Black – “Per-Object Behavior in Ruby”. Definitely the most enlightening talk amongst the ones I’ve listened to. Writing more about it would be a waste of time, just grab the video and watch it. Made me a better Ruby programmer.

15.15: Nic Williams – “Meta-Meta-Programming with Ruby”. I was disappointed. If I had to give it “the most” title, it would be “the most disappointing talk”. Dr Nic is a well-known man in Ruby and Rails community, and – to say the least without writing pages about great things he’s done – he definitely deserves his fame and thus I was looking forward to listening to a talk by someone of such format. But, as I wrote earlier, I was disappointed. Dr Nic put too much weight on making his talk easy, witty and full of jokes and, well, hasn’t put a lot of technical knowledge into his talk. Sure, it was a bit philosophical, but definitely not worth 45 minutes of Ruby conference.

After spending some time on Lightning Talks (few were great, few weren’t) we’ve decided to get some more of Prague’s views and beer (I also had to give my talk a few finishing touches and some polish), and thus left Euruko until sunday.

... so let's publish my impressions from march'08 EuRuKo. Finally, that is.

This is a translation of Radarek's excellent article.

You can write FORTRAN in any language

A language that doesn’t affect the way you think about programming is not worth knowing

You can write C code in Ruby:

Car = Struct.new(:model, :color, :opt)

CAR_MODEL_BWM       = 0
CAR_MODEL_AUDI      = 1

CAR_OPT_GAS         = 0x01
CAR_OPT_AIR_COND    = 0x02
CAR_OPT_ROOF_RACK   = 0x04

CAR_COLOR_BLACK     = 0
CAR_COLOR_RED       = 1
CAR_COLOR_GREEN     = 3
CAR_COLOR_BLUE      = 4
CAR_COLOR_WHITE     = 5

CAR_MODEL_NAMES = [
  "BMW",
  "AUDI"
]

CAR_COLOR_NAMES = [
  "black",
  "red",
  "green",
  "blue",
  "white"
]

def car_create(model, color, opt = 0)
  car = Car.new
  car.model = model
  car.color = color
  car.opt   = opt
  return car
end

def car_print(car)
  printf("[Car] model: %s, color: %s\n", CAR_MODEL_NAMES[car.model], CAR_COLOR_NAMES[car.color])
  printf("Options: \n")
  if car_has_gas(car)
    printf(" - gas\n")
  end
  if car_has_air_cond(car)
    printf(" - air condition\n")
  end
  if car_has_roof_rack(car)
    printf(" - roof rack\n")
  end
end

def car_max_speed(car)
  case car.model
  when CAR_MODEL_AUDI
    return 200
  when CAR_MODEL_BWM
    return 220
  else
    return -1
  end
end

def car_has_gas(car)
  return (car.opt & CAR_OPT_GAS) != 0
end

def car_has_air_cond(car)
  return (car.opt & CAR_OPT_AIR_COND) != 0
end

def car_has_roof_rack(car)
  return (car.opt & CAR_OPT_ROOF_RACK) != 0
end

car = car_create(CAR_MODEL_BWM, CAR_COLOR_BLACK, CAR_OPT_AIR_COND)
car_print(car

You can write Java code in Ruby:

class User
  def initialize(name, age)
    self.setName(name);
    self.setAge(age);
  end
  
  def setName(name)
    @name = name;
  end
  
  def getName()
    return @name;
  end
  
  def setAge(age)
    @age = age;
  end
  
  def getAge()
    return @age;
  end
end

class Iterator
  def initialize(array)
    @index = 0;
    @array = array
  end
  
  def hasNext()
    return @index < @array.length();
  end
  
  def getNext()
    @index += 1;
    return @array[@index - 1];
  end
end

array = [User.new("john", 20), User.new("ala", 30), User.new("dave", 15)];
it = Iterator.new(array);
while (it.hasNext())
  user = it.getNext();
  puts("Name: " + user.getName() + ", Age: " + user.getAge().to_s());
end

You can write Perl code in Ruby:

while gets
  chomp
  next if /^#/ or /^!/
  break if /quit/
  
  if /(\d+)/
    print $1
  end
end

The purpose of this note: if you want to program in Ruby, learn the language properly, not just the syntax with standard library. Learn it long enough (or effective enough) until you learn it's style, mindset, idioms and nuances. Then write your Ruby programs using these idioms, standards, way of naming and structing and so on. Don't stop until you learn almost all about it - and when you do, you'll find a lot more to be learned about. You probably already know what OOP is, so put emphasis on non-obvious basics, like method-calling, mixins, includes, extends, metaclasses and so on. Experience life without static typing, experience the power of Ruby's metaprogramming possibilities (and dangers).

Otherwise there'll be a chance you're not writing Ruby, but some other language using simply Ruby syntax. If so - why pretend to write Ruby?

Back from Euruko 2008

March 31st, 2008

We just got back from Prague after attending to European Ruby Conference. Promise to write a review after we get everything running smoothly again (including this blog).