If performance were an issue, I'd benchmark it as is, then test it using a find_by_sql. So far, performance hasn't been an issue for me. I'd also have to figure out how to go about initializing models with the values pulled from that find_by_sql. Premature optimization, and all that.
MIchael Koziarski brings up an interesting point, however, and I'm interested in hearing discussion on that as well.
class User < ActiveRecord::Base
has_many :roles
has_many :projects, :through => :roles
end
class Project < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
has_many :notes
end
class NotesController < ApplicationController
before_filter :find_project
before_filter :find_task
before_filter :find_note
def show
end
protected
def find_project
@project = current_user.projects.find(params[:project_id])
end
def find_task
@task = @project.tasks.find(params[:task_id])
end
def find_note
@note = @task.notes.find(params[:id])
end
end
Notice each find is scoped using it's AR associations proxy, starting from current_user.projects
Those filters are easily memcached when you start hitting loads, and are easily stubbed in your controller spec. You can also combine some of those calls with an :include.
Also, some of the actual find_xx methods belong in application controller.
Sure. Very much so... and that's exactly how I've been doing it. So what I understand is that it's perfectly fine to query the database that many times, because it's good for security and data integrity. I can live with that. Just wanted to make sure that was the best way to explain it to my students. Some people will surely look at the sql logs and see four separate (albeit small) queries and wonder why that's necessary, so I want to have a good answer for them.
Thanks everyone! I really appreciate it.
To add, shouldn't security/authorization be implemented mostly in the model? In Tom's Hobo, all of authorization mechanism take place in the model. The model should know which requests (users) should be able to access (read/update/delete) it (or parts of it, e.g. individual fields). The controller only passes authorization requests to the model, it obeys what the models are supposed to allow or deny.
Using polymorphic paths to be more logical and nice to look is great... but if security is one added advantage, is it really the appropriate place to put such (only!) security measure?
Depends on the level you have to authorize on. I've never written an application where is was necessary to drop down to model level to ensure people didn't access information they shouldn't access.