Skip to content

Instantly share code, notes, and snippets.

@generalzhou
Last active December 18, 2015 00:48
Show Gist options
  • Save generalzhou/5698941 to your computer and use it in GitHub Desktop.
Save generalzhou/5698941 to your computer and use it in GitHub Desktop.

ActionController Basics

What is the action controller and how can we use it?

A controller is a Ruby class which inherits from ApplicationController and has methods just like any other class.

class ApplicationController < ActionController::Base
	def methods_every_controller_can_use
	end
end

class UserController < ApplicationController
	def method_specific_to_user_controller
	end
end

When your application receives a request, the routing will determine which controller and action to run, then Rails creates an instance of that controller and runs the method with the same name as the action.

a route '/clients/new'

looks for

class ClientsController
  def new
  end
end

Which by default looks for a view call ruby /views/clients/new.html.erb

####Filters

Methods to be run before, during or after controller actions. Can be inherited from ActionController (think about them like validations)

class ApplicationController < ActionController::Base
  before_filter :require_login
 
  private
 
  def require_login
    unless logged_in?
      flash[:error] = "You must be logged in to access this section"
      redirect_to new_login_url # halts request cycle
    end
  end

A render or redirect in before_filter will cancel any following actions and filters.

Obviously you don't necessarily want this to run before ALL actions, so you can skip like this:

class LoginsController < ApplicationController
  skip_before_filter :require_login, :only => [:new, :create]
end

The options can also be used to run/ignore filters selectively

After filters run after the action. Cannot stop the action itself.

class ApplicationController < ActionController::Base
  after_filter :stuff_to_do_after_action
end

Around filters are general purpose filters that can run code before and after the action. The use of the yield keyword determines exactly when the action is performed.

class ApplicationController < ActionController::Base
	around_filter :stuff_before_and_after_action
	
	def stuff_before_and_after_action
		stuff_before
		yield # this is the action itself
		stuff_after
	end
end

####Cookies yummmmm

They have these properties:

  • Cookies persist until they are deleted, reset, or expired.
  • They are sent back and forth in the header of every HTTP request and response
  • They can only contain about 4kb of data
  • You can send and retrieve more than one cookie

#####Cookies They are stored in plaintext, and should be used for general settings like locale. Persist across sessions (clearing session cookies won't clear this).

Access this like: ruby cookies[:cookie_key]

Note that while for session values you set the key to nil, to delete a cookie value you should use cookies.delete(:key).

#####Sessions Sessions are persisted across requests. They are encrypted and should store session data (like who is logged in)

You know this stuff

Access this like: ruby session[:session_key]

#####Flash Flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages

class LoginsController < ApplicationController
  def destroy
    session[:current_user_id] = nil
    flash[:notice] = "You have successfully logged out"
    redirect_to root_url
  end
end
redirect_to root_url, :notice => "You have successfully logged out"

This automatically sets flash[:notice] = "You have successfully logged out"

The symbols

:notice, :error, :alert, :success

are automatically set as flash params

if you want to keep the flash params for more than one redirect, user

flash.keep

Flash is meant to be used for the next redirect. However, if you want to use the flash variable on the same page where it's set, just call

flash.now[:notice]

Request and Response methods

There are 2 accessor methods that ActionController gives to you, called request and response. They correspond to the HTTP request received and the response sent.

####Request properties:

Property of request Purpose
host The hostname used for this request.
domain(n=2) The hostname’s first n segments, starting from the right (the TLD).
format The content type requested by the client.
method The HTTP method used for the request.
get?, post?, put?, delete?, head? Returns true if the HTTP method is GET/POST/PUT/DELETE/HEAD.
headers Returns a hash containing the headers associated with the request.
port The port number (integer) used for the request.
protocol Returns a string containing the protocol used plus “://”, for example “http://”.
query_string The query string part of the URL, i.e., everything after “?”.
remote_ip The IP address of the client.
url The entire URL used for the request.

Parameter getters:

  • path_parameters: parameters that were recognized by the routing that led to this controller and action
  • query_parameters: parameters that were sent as part of the query string
  • request_parameters: contains parameters sent as part of the post body action.

####Response Object This contains the server response that is built up during the execution of the controller and view code. Some of these params have setters allowing you to directly modify the response.

For example, if you want to add or change a header, just assign it to response.headers this way:

response.headers["Content-Type"] = "application/pdf"
Property of response Purpose
body This is the string of data being sent back to the client. This is most often HTML.
status The HTTP status code for the response, like 200 for a successful request or 404 for file not found.
location The URL the client is being redirected to, if any.
content_type The content type of the response.
charset The character set being used for the response. Default is “utf-8”.
headers Headers used for the response.

Cool thing we noticed:

<form accept-charset="UTF-8" action="/clients" method="post">
  <input type="text" name="client[name]" value="Acme" />
  <input type="text" name="client[phone]" value="12345" />
  <input type="text" name="client[address][postcode]" value="12345" />
  <input type="text" name="client[address][city]" value="Carrot City" />
</form>

HTTP Digest Authentication

Very basic HTTP request authentication when trying to access protected files on server. Sends data through headers.

Params

match '/clients/:status' => 'clients#index', :foo => "bar"
'/clients/active' sets params[:status] to active, params[:foo] => 'bar'
{ "company": { "name": "acme", "address": "123 Carrot Street" } }

You’ll get:

params[:company] as { :name => “acme”, “address” => “123 Carrot Street” }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment