Skip to content

Instantly share code, notes, and snippets.

@rloomba
Last active December 14, 2015 19:49
Show Gist options
  • Save rloomba/5139613 to your computer and use it in GitHub Desktop.
Save rloomba/5139613 to your computer and use it in GitHub Desktop.

ActionController

In Sinatra, routes/controllers/actions combined into one entity. In rails, these things are separate. There are seven main actions: index, show, create, new, edit, update, destroy

1. Rails Routing

    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

Sinatra Controller

get '/posts' do
  @posts = Post.all
  erb :posts
end

get '/posts/:id' do
  @post = Post.find(params[:id])
  erb :post
end

get '/posts/new' do
  @post = Post.new
  erb :new_post
end

get '/posts/:id/edit' do
  @post = Post.find(params[:id])
  erb :new_post
end

post '/posts' do
  @post = Post.create(params[:post])
  redirect '/posts'
end

put '/posts/:id' do
  @post = Post.find(params[:id])
  @post.update_attributes(params[:post])
  redirect '/posts'
end

delete '/posts/:id' do
  @post = Post.find(params[:id])
  @post.destroy
end

Rails Controller

# posts_controller.rb
class PostsController < ApplicationController
  # GET /posts
  def index
    @posts = Post.all
  end

  # GET /posts/1
  def show
    @post = Post.find(params[:id])
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
    @post = Post.find(params[:id])
  end

  # POST /posts
  def create
    @post = Post.new(params[:post])
    
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        # another way to redirect redirect_to :action => 'show', :id => @entry.id
      else
        format.html { render action: "new" }
      end
  end

  # PUT /posts/1
  def update
    @post = Post.find(params[:id])

      if @post.update_attributes(params[:post])
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
      else
        format.html { render action: "edit" }
    end
  end

  # DELETE /posts/1
  def destroy
    @post = Post.find(params[:id])
    @post.destroy

      format.html { redirect_to posts_url }
  end
end

2. Parameters

  • there are different ways to pass params, in body of post request or in the get request in URL after ?
  • rails converts params to hash
  • post to /products
  • get request at /products?key1=value1&key2=value2
class ClientsController < ActionController::Base
  # This action uses query string parameters because it gets run
  # by an HTTP GET request, but this does not make any difference
  # to the way in which the parameters are accessed. The URL for
  # this action would look like this in order to list activated
  # clients: /clients?status=activated
  def index
    if params[:status] == "activated"
      @clients = Client.activated
    else
      @clients = Client.unactivated
    end
  end
 
  # This action uses POST parameters. They are most likely coming
  # from an HTML form which the user has submitted. The URL for
  # this RESTful request will be "/clients", and the data will be
  # sent as part of the request body.
  def create
    @client = Client.new(params[:client])
    if @client.save
      redirect_to @client
    else
      # This line overrides the default rendering behavior, which
      # would have been to render the "create" view.
      render :action => "new"
    end
  end
end
  • formatting in URL params to an array: GET /clients?ids[]=1&ids[]=2&ids[]=3

3. Sessions

#4 ways to store cookies -ActionDispatch::Session::CookieStore –> Stores everything on the client. -ActiveRecord::SessionStore –> Stores the data in a database using Active Record. -ActionDispatch::Session::CacheStore –> Stores the data in the Rails cache. -ActionDispatch::Session::MemCacheStore –> Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).

accessing session is same as Sinatra to clear a specific key, set it to nil

  class ApplicationController < ActionController::Base
 
  private
 
  # Finds the User with the ID stored in the session with the key
  # :current_user_id This is a common way to handle user login in
  # a Rails application; logging in sets the session value and
  # logging out removes it.
  def current_user
    @_current_user ||= session[:current_user_id] &&
      User.find_by_id(session[:current_user_id])
  end
  def destroy
    # Remove the user id from the session
    @_current_user = session[:current_user_id] = nil
    redirect_to root_url
  end
end

4. Flash

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"

example of flash.keep, persist flash instead of deleting

class MainController < ApplicationController
  # Let's say this action corresponds to root_url, but you want
  # all requests here to be redirected to UsersController#index.
  # If an action sets the flash and redirects here, the values
  # would normally be lost when another redirect happens, but you
  # can use 'keep' to make it persist for another request.
  def index
    # Will persist all flash values.
    flash.keep
 
    # You can also use a key to keep only some kind of value.
    # flash.keep(:notice)
    redirect_to users_url
  end
end
  • example of flash.now, flash is by default only avail to next request, if you want flash available in the same request, use flash.now
class ClientsController < ApplicationController
  def create
    @client = Client.new(params[:client])
    if @client.save
      # ...
    else
      flash.now[:error] = "Could not save client"
      render :action => "new"
    end
  end
end

5. Cookies

  • similar to sessions

cookies[:this] = that

6. Filters

# Given these filters
#   after_filter :after
#   around_filter :around
#   before_filter :before
#
# The filter chain will look like:
#
#   ...
#   . \
#   .  #around (code before yield)
#   .  .  \
#   .  .  #before (actual filter code is run)
#   .  .  .  \
#   .  .  .  execute controller action
#   .  .  .  /
#   .  .  ...
#   .  .  /
#   .  #around (code after yield)
#   . /
#   #after (actual filter code is run)
#

#before

  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
 
  # The logged_in? method simply returns true if the user is logged
  # in and false otherwise. It does this by "booleanizing" the
  # current_user method we created previously using a double ! operator.
  # Note that this is not common in Ruby and is discouraged unless you
  # really mean to convert something into true or false.
  def logged_in?
    !!current_user
  end
  end

#around scope of the filter is wrapped around the controller transactional filter, if there's an error, rollback filter after effect of filter happens after the controller action

skipping a filter

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

Let's say we want to run our helper method authenticate_user! before each request, except when creating a new user

in our application controller we would have:

before_filter authenticate_user!

in our users controller we would have:

skip_before_filter :authenticate_user!, :only => [:new, :create]

Request and Response Object objects available in every controller response.headers["Content-Type"] = "application/pdf"

outside resources:

  1. http://guides.rubyonrails.org/action_controller_overview.html
  • great overview on all the features of action controller
  1. http://railscasts.com/episodes/395-action-controller-walkthrough
  2. http://api.rubyonrails.org/ => go to Classes and click on ApplicationController, has more details on filters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment