Rails: Power to the filters
Rails before_filters in controllers can help you keep your code DRY.
I have coded cases where all action functionality was included in 2-3 before_filters.
I have coded cases where all action functionality was included in 2-3 before_filters.
I’ll try to showcase some of the methods that work for me.
Authentication
The most commonly used before_filter should be that of authentication, and since this is global you can place it in you ApplicationController.
01.
class
ApplicationController < ActionController::Base
02.
session
:session_key
=>
'_fortytwo_session_id'
03.
04.
before_filter
:fetch_logged_user
05.
06.
def
authenticate
07.
unless
@logged_user
08.
#unauthorized access
09.
redirect_to login_url,
:status
=>
401
10.
return
false
11.
end
12.
end
13.
14.
def
fetch_logged_user
15.
16.
unless
session[
:user_id
].blank?
17.
@logged_user
= User.find(session[
:user_id
])
18.
end
19.
20.
rescue
ActiveRecord::RecordNotFound
21.
end
22.
23.
end
Now, in every action, in every controller we have a @logged_user object. If it’s not nil , then we have an authenticated user.
So if we want to restrict access to authenticated users in a certain controller for some actions, we just need a before_filter for the authenticate function.
So if we want to restrict access to authenticated users in a certain controller for some actions, we just need a before_filter for the authenticate function.
1.
class
UsersController < ApplicationController
2.
before_filter
:authenticate
,
:except
=>
:login
3.
endre
CRUD Operations
Models usually have the common CRUD actions (new, edit, update, delete, create), and some other actions that operate on a specific model record. If you add authentication and probably authorization (only the owner of a blog post can change his content for example), things can get complicated. Unless…
01.
class
BlogController < ApplicationController
02.
#authenticate is in our ApplicationController
03.
before_filter
:authenticate
,
:except
=>
:show
04.
before_filter
:fetch_post
,
:only
=> [
:show
,
:edit
,
:update
,
:delete
]
05.
before_filter
:authorise_as_owner
,
:only
=> [
:edit
,
:update
,
:delete
]
06.
07.
private
08.
09.
def
fetch_post
10.
@post
= Post.find(params[
:id
])
11.
rescue
ActiveRecord::RecordNotFound
12.
#there is no such post
13.
flash[
:alert
] =
"Got lost?"
14.
redirect_to error_url,
:status
=>
404
15.
return
false
16.
end
17.
18.
def
authorise_as_owner
19.
unless
@post
.user_id ==
@logged_user
.id
20.
#You don't belong here. Go away.
21.
flash[
:alert
] =
"Mind your own business"
22.
redirect_to error_url,
:status
=>
401
23.
end
24.
end
25.
26.
end
If you are using roles, you can extend the authorisation behaviour (so that admins can edit any post) like this:
1.
def
authorise
2.
unless
@post
.user_id ==
@logged_user
.id ||
@logged_user
.is_admin?
3.
#You don't belong here. Go away.
4.
flash[
:alert
] =
"Mind your own business"
5.
redirect_to error_url,
:status
=>
401
6.
end
7.
end
No comments:
Post a Comment