После того, как определили routes, определяют контроллеры (это C в MVC паттерне). Эта сущность находится между слоем отображения (View) и слоем моделей данных (Model).
В Ruby контроллер — класс, наследованный от ApplicationController (наследован от ActionController::Base). Когда приложение получает запрос, маршрутизация определяет контроллер и действие для запуска; Rails создает инстанс контроллера и вызывает метод, соответствующий объявленному действию
Пример контроллера
# resources :clients, only: :new# -> /clients/new -> Add new clientclassClientsController<ApplicationControllerdefnew @client =Client.new# @client becomes accessible in the view # Автоматом доступен модель Clientendend
Параметры в контроллере
Доступ к GET/POST параметрам осуществляется через params
classClientsController<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=activateddefindexif params[:status] =="activated" @clients =Client.activatedelse @clients =Client.inactivatedendend# 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.defcreate @client =Client.new(params[:client])if @client.save redirect_to @clientelse# This line overrides the default rendering behavior, which# would have been to render the "create" view. render "new"endendend
rescue_from
Позволяет обработать определенный тип эксепшена в текущем и во всех дочерних контроллерах кастомным способом
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:
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_store
Rails 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:
classApplicationController<ActionController::Baseprivate# 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.defcurrent_user @_current_user ||= session[:current_user_id] &&User.find_by(id: session[:current_user_id])endend
To store something in the session, just assign it to the key like a hash:
classLoginsController<ApplicationController# "Create" a login, aka "log the user in"defcreateif 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_urlendendend
To remove something from the session, delete the key/value pair:
classLoginsController<ApplicationController# "Delete" a login, aka "log the user out"defdestroy# Remove the user id from the session session.delete(:current_user_id)# Clear the memoized current user @_current_user =nil redirect_to root_urlendend
flash
Есть объект 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 =MyCustomSerializer
Filters
Это методы, которые вызываются before, after и around действия контроллера. Фильтры наследуются. Если определить фильтр в ApplicationController, то он будет срабатывать в каждом контроллере вашего приложения:
classApplicationController<ActionController::Base before_action :require_loginprivatedefrequire_loginunless logged_in? flash[:error] ="You must be logged in to access this section" redirect_to new_login_url # halts request cycleendendend
Если мы хотим скипнуть какой-нибудь фильтр для нашего контроллера: