In this sixteenth part of an eighteen-part series on the Action Pack library for Rails, you'll learn how to apply filters to controllers and how to use Action View helpers. This article is excerpted from chapter six of the book Beginning Rails: From Novice to Professional, written by Jeffery Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Filters, Controllers and Helpers in Action Pack (Page 1 of 2 )
Applying Filters to Controllers
You apply filters using a declarative syntax. In this case, we want to check that a user is authenticated before we process a protected action, so we’ll use the before_filter . Add the filter to the events controller, just inside the class body, as shown in Listing 6-22.
Listing 6-22. Before Filter Added in app/controllers/events_controller.rb
Notice how we’re able to selectively apply the filter to specific actions. Here, we want every action to be protected except for index and show . The :except modifier accepts either a single value or an array. We’re using an array here. If you want to protect only a few actions, you can use the :only modifier, which, as you would expect, behaves the opposite of :except .
We also want to use a filter in the users controller. Right now, anyone can edit a user as long as they know the user ID. This would be risky in the real world. Ideally, we want the edit and update actions to respond only to the currently logged-in user, allowing that user to edit his profile. To do this, instead of retrieving User.find(params[:id]) , we’ll retrieve the current_user and apply a filter to protect the edit and update actions. Listing 6-23 shows the latest version of the users controller, the updated code is highlighted in bold.
Listing 6-23. Before Filter Added in app/controllers/users_controller.rb
def create @user = User.new(params[:user]) if @user.save
flash[:notice] = 'Thanks for signing up!' redirect_to :controller => 'events', :action => 'index' else render :action => 'new' end end
def edit @user = current_user end
def update @user = current_user if current_user.update_attributes(params[:user])
flash[:notice] = 'Information updated' redirect_to :action => 'show', :id => current_user.id else render :action => 'edit' end end
def login if request.post?
if user = User.authenticate(params[:login], params[:password]) session[:user_id] = user.id redirect_to :controller => 'events', :action => 'index'
else flash[:notice] = 'Invalid login/password combination' end end end
session[:user_id] = nil
redirect_to :action => 'login'
Adding Finishing Touches
We’re almost finished with our work in this chapter. Only a few tasks remain. We need to spruce up our templates a bit and make them a little cleaner. We also need to make it possible for event owners to edit and delete their events. Finally, we want to update the layout and apply some CSS styles to make things look pretty. Ready? Let’s get started!