Controllers
Intro
ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠ»ΠΈ routes, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΡ (ΡΡΠΎ C Π² MVC ΠΏΠ°ΡΡΠ΅ΡΠ½Π΅). ΠΡΠ° ΡΡΡΠ½ΠΎΡΡΡ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ»ΠΎΠ΅ΠΌ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (View) ΠΈ ΡΠ»ΠΎΠ΅ΠΌ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π΄Π°Π½Π½ΡΡ (Model).
Π Ruby ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ β ΠΊΠ»Π°ΡΡ, Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΎΡ ApplicationController (Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ ΠΎΡ ActionController::Base). ΠΠΎΠ³Π΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π·Π°ΠΏΡΠΎΡ, ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ°; Rails ΡΠΎΠ·Π΄Π°Π΅Ρ ΠΈΠ½ΡΡΠ°Π½Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° ΠΈ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΠΎΠΌΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ
ΠΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°
# resources :clients, only: :new
# -> /clients/new -> Add new client
class ClientsController < ApplicationController
    def new
        @client = Client.new # @client becomes accessible in the view 
                             # ΠΠ²ΡΠΎΠΌΠ°ΡΠΎΠΌ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΠΌΠΎΠ΄Π΅Π»Ρ Client
    end
endΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅
ΠΠΎΡΡΡΠΏ ΠΊ GET/POST ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΡΠ΅Π· params
class ClientsController < ApplicationController
  # This action uses query string parameters because it gets run
  # by an HTTP GET request, but this does not make any difference
  # to how the parameters are accessed. The URL for
  # this action would look like this to list activated
  # clients: /clients?status=activated
  def index
    if params[:status] == "activated"
      @clients = Client.activated
    else
      @clients = Client.inactivated
    end
  end
  # This action uses POST parameters. They are most likely coming
  # from an HTML form that 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 "new"
    end
  end
endrescue_from
ΠΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ ΡΠΈΠΏ ΡΠΊΡΠ΅ΠΏΡΠ΅Π½Π° Π² ΡΠ΅ΠΊΡΡΠ΅ΠΌ ΠΈ Π²ΠΎ Π²ΡΠ΅Ρ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°Ρ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ
class WebController < ApplicationController
    rescue_from ActiveRecord::RecordNotFound, with: :error_not_found
    
    def error_not_found(error)
        return render template: 'errors/404', layout: false, status: :not_found
    end
endStrong Parameter API
permit
Π€ΡΠ½ΠΊΡΠΈΡ Ρ params, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²Π΅ΡΠ½ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΊΠ°Π·Π°Π½Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ². ΠΠ΅Π»Π°Π΅ΡΡΡ Π΄Π»Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ.
params.permit(:id)
def product_params
    params.require(:product).permit(:name, data: {})
endrequire
Π£ΠΊΠ°Π·ΡΠ²Π°Π΅Ρ, ΡΡΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»Π΅Π½
Session
Your application has a session for each user in. The session is only available in the controller and the view and can use one of several of different storage mechanisms:
- ActionDispatch::Session::CookieStore- Stores everything on the client.
- ActionDispatch::Session::CacheStore- Stores the data in the Rails cache.
- ActionDispatch::Session::ActiveRecordStore- Stores the data in a database using Active Record (requires the- activerecord-session_storegem).
- ActionDispatch::Session::MemCacheStore- Stores the data in a memcached cluster (this is a legacy implementation; consider using- CacheStoreinstead).
All session stores use a cookie to store a unique ID for each session.
If you need a different session storage mechanism, you can change it in an initializer:
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails g active_record:session_migration")
# Rails.application.config.session_store :active_record_storeRails sets up a session key (the name of the cookie) when signing the session data. These can also be changed in an initializer:
# Be sure to restart your server when you modify this file.
Rails.application.config.session_store :cookie_store, key: '_your_app_session'You can also pass a :domain key and specify the domain name for the cookie:
# Be sure to restart your server when you modify this file.
Rails.application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"Rails sets up (for the CookieStore) a secret key used for signing the session data in config/credentials.yml.enc. This can be changed with bin/rails credentials:edit.
Accessing the Session
Session values are stored using key/value pairs like a hash:
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
endTo store something in the session, just assign it to the key like a hash:
class LoginsController < ApplicationController
  # "Create" a login, aka "log the user in"
  def create
    if user = User.authenticate(params[:username], params[:password])
      # Save the user ID in the session so it can be used in
      # subsequent requests
      session[:current_user_id] = user.id
      redirect_to root_url
    end
  end
endTo remove something from the session, delete the key/value pair:
class LoginsController < ApplicationController
  # "Delete" a login, aka "log the user out"
  def destroy
    # Remove the user id from the session
    session.delete(:current_user_id)
    # Clear the memoized current user
    @_current_user = nil
    redirect_to root_url
  end
endflash
ΠΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ flash, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ Π·Π°ΠΏΡΠΎΡΡ
Cookies
ΠΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ cookie.
ΠΠΎΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π»ΠΈΡΡ Π² ΠΊΠΎΠ½ΡΠΈΠ³Π΅, ΠΊΠ°ΠΊ Π±ΡΠ΄ΡΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
Rails.application.config.action_dispatch.cookies_serializer = :json
# :json β ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π΄Π»Ρ Π½ΠΎΠ²ΡΡ
 ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π΄Π»Ρ ΡΡΠ°ΡΡΠΉ β :marshal.
# Custom serialized (implement load ΠΈ dump ΠΌΠ΅ΡΠΎΠ΄Ρ):
Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializerFilters
ΠΡΠΎ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ before, after ΠΈ around Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°. Π€ΠΈΠ»ΡΡΡΡ Π½Π°ΡΠ»Π΅Π΄ΡΡΡΡΡ. ΠΡΠ»ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΡΠΈΠ»ΡΡΡ Π² ApplicationController, ΡΠΎ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
class ApplicationController < ActionController::Base
  before_action :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
endΠΡΠ»ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΡΠΊΠΈΠΏΠ½ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡΠ΄Ρ ΡΠΈΠ»ΡΡΡ Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°:
class LoginsController < ApplicationController
  skip_before_action :require_login, only: [:new, :create]
endLast updated