Render
The render directive is used to generate a web page, typically a view.
Render has several options. Render defaults to the view with the method name, in the folder with the name of the current controller, using the layout with the controller name if it exists, or the application layout otherwise. In the
Edit
method of PostsController
, these two are equivalent:render
render :action => 'edit', :layout => 'posts'
Indeed, even the word render is unnecessary; Rails will default to the above even if no render directive is present, as seen in the
Edit
method of PostsController
(behind the scenes Rails has a variable that notes when a render has been done, to ensure one gets done even if not specified, and to throw an error if you try to do it twice).Render has several options.
:action # Render using the view app/views/[controller]/[action].html.erb
# (note that the action named need not exist in any controller)
:template # As :action, but using the file app/views/[template].html.erb.
# Use this for consistent views between controllers.
:file # Render the given file (needs the absolute path, which seems a
# bit of a drawback to me). Layout not used.
:text # Render the given text as the web page. Strangely, you can use
# this to return an image (render :text => image.to_blob).
:inline # As text, but ERb is parsed.
:partial # Render as a partial web page (can be updated while the rest
# of the web page remains).
:nothing # Return a web page with no content.
:status # The HTTP code to be returned (returning :status => :success
# with :text causes an error, and it seems to be ignored for :action).
:content_type # For an image, this mght be :content_type => 'image/gif'
# My attempts to change the controller failed; it was just ignored.
# I had hoped to reuse the view of another controller; use template
# to do that instead!
More on render:
http://api.rubyonrails.org/classes/ActionController/Base.html#M000848
Filters
Filters are directives to perform certain methods before or after every action. A
before_filter
might be used to ensure a user has been authenticated, or for logging purposes, for instance.Filters should appear at the start of the class, in the form:
before_filter :my_filter
Set up
my_filter
like any normal method. If it returns a Boolean false, the action will be aborted. Alternatively, your filter could initiate a redirect (say, pointing the user to the login page).There are several different flavours of filters:
before_filter
prepend_before_filter # Do this filter before
other before filters
append_before_filter # Do this filter after other
before filters
after_filter
prepend_after_filter
append_after_filter
around_filter # use the yield keyword in the
filter when the output would go. Useful for
capturing exceptions
prepend_around_filter
append_around_filter
skip_filter # Want to skip filters in a superclass?
Filters apply to all actions in your controller (or all actions in your application if they are in ApplicationController). However, you can limit them:
:only => :edit # Apply this filter to the edit action only
:except => [:new, :delete] # Do not apply to the :new or :delete actions
Reference
http://api.rubyonrails.com/classes/ActionController/Filters/ClassMethods.html
This site uses a filter to avoid repetitive loading of objects
http://manuscripttranscription.blogspot.com/2007/06/rails-short-introduction-to.html
Using a Filter to Test if a Record Exists
The find method of ActiveRecord will throw an exception if no record is found with that ID. This can happen even if your web app is perfect, for example when the user makes a mistake typing in a URL directly (as Rails interprates any unknown as being an ID). How do you handle that?
You have three choices. All the examples I have come across just ignore it. Let Rails throw the exception, and deal with it itself. In the development environment this means giving a web page with a stack trace; in the production environment a page is displayed telling the user that the administrator has been informed of the problem. A better solution is to catch the exception and handle it yourself, giving the user a more helpful result that does not leave the impression that your software is buggy!
However, my prefered solution is to avoid the exception altogether, by testing whether the record exists before trying to retrieve. And the best place to do that is in a before_filter. You might set the filter up like this (note that these are just the typical methods that retrieve a specific record by ID):
before_filter :check_id, :only =>
[ :edit, :update, :destroy, :show]
Then you include the method (which should be protected, so it cannot be called as an action):
protected
def check_id
return if Post.exists? params[:id]
@ref = params[:id]
render :action => 'no_show'
end
This simply checks the record exists, and if not renders an alternative page.
Struggling with Ruby: Contents Page
No comments:
Post a Comment