Spec-Zone.ru › Ruby on Rails 4.1

класс ActionController::Base

Родитель:
Metal

Контроллеры действий являются ядром веб-запроса в Rails. Они состоят из одного или нескольких действий, которые выполняются при запросе, а затем либо отображают шаблон, либо перенаправляют на другое действие. Действие определяется как публичный метод в контроллере, который автоматически станет доступным веб-серверу через маршруты Rails.

По умолчанию, только ApplicationController в приложении Rails наследует от ActionController::Base. Все остальные контроллеры, в свою очередь, наследуют от ApplicationController. Это предоставляет вам один класс для настройки таких параметров, как защита от подделки запросов и фильтрация чувствительных параметров запроса.

Пример контроллера может выглядеть так:

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.create params[:post]
    redirect_to posts_path
  end
end

Действия по умолчанию отображают шаблон в каталоге app/views , соответствующем имени контроллера и действия после выполнения кода в действии. Например, действие index контроллера PostsController по умолчанию отобразит шаблон app/views/posts/index.html.erb после заполнения переменной экземпляра @posts.

В отличие от действия index, действие create не отобразит шаблон. После выполнения своей основной задачи (создания новой записи), оно инициирует перенаправление вместо этого. Это перенаправление работает, возвращая внешний HTTP-ответ «302 Перемещено», который перенаправляет пользователя на действие index.

Эти два метода представляют два основных архетипа действий, используемых в контроллерах действий. Получение и отображение, и выполнение и перенаправление. Большинство действий являются вариациями этих тем.

Запросы

Для каждого запроса маршрутизатор определяет значение ключей controller и action. Они определяют, какой контроллер и какое действие вызываются. Остальные параметры запроса, сессия (если она доступна) и весь запрос со всеми HTTP-заголовками доступны действию через методы доступа. Затем выполняется действие.

Объект полного запроса доступен через аксессор request и используется в основном для запроса HTTP-заголовков:

def server_ip
  location = request.env["REMOTE_ADDR"]
  render plain: "This server hosted at #{location}"
end

Параметры

Все параметры запроса, будь то GET или POST-запрос или из URL, доступны через метод params, который возвращает хэш. Например, действие, выполненное через /posts?category=All&limit=5 , будет включать { "category" => "All", "limit" => "5" } в params.

Также можно создать многомерные хэши параметров, указав ключи в квадратных скобках, например:

<input type="text" name="post[name]" value="david">
<input type="text" name="post[address]" value="hyacintvej">

Запрос, полученный из формы с этими входными данными, будет включать { "post" => { "name" => "david", "address" => "hyacintvej" } }. Если бы адрес был назван post[address][street], params включали бы { "post" => { "address" => { "street" => "hyacintvej" } } }. Глубже вложенности нет предела.

Сессии

Сессии позволяют хранить объекты между запросами. Это полезно для объектов, которые еще не готовы к сохранению, например, объект Signup, созданный в многостраничном процессе, или объекты, которые не сильно меняются и постоянно необходимы, например, объект User для системы, требующей входа. Однако сессии не следует использовать в качестве кэша для объектов, которые, вероятно, могут быть изменены без ведома пользователя. Обычно это слишком сложно для синхронизации - с этим уже отлично справляются базы данных.

Вы можете поместить объекты в сессию, используя метод session, который обращается к хэшу:

session[:person] = Person.authenticate(user_name, password)

И снова извлечь через тот же хэш:

Hello #{session[:person]}

Для удаления объектов из сессии можно либо назначить отдельный ключ nil:

# removes :person from session
session[:person] = nil

или удалить всю сессию с помощью reset_session.

Сессии по умолчанию хранятся в cookie-файле браузера, который криптографически подписан, но не зашифрован. Это предотвращает вмешательство пользователя в сессию, но также позволяет ему видеть её содержимое.

Не храните конфиденциальную информацию в сессиях на основе cookie!

Ответы

Каждое действие приводит к ответу, который содержит заголовки и документ, которые должны быть отправлены в браузер пользователя. Фактический объект ответа генерируется автоматически через рендеринг и перенаправления и не требует вмешательства пользователя.

Отображения

Контроллер действий отправляет содержимое пользователю, используя один из пяти методов отображения. Наиболее универсальным и распространенным является отображение шаблона. В Action Pack включен Action View, который позволяет отображать шаблоны ERB. Он настраивается автоматически. Контроллер передает объекты в представление, назначив переменные экземпляра:

def show
  @post = Post.find(params[:id])
end

которые затем автоматически доступны представлению:

Title: <%= @post.title %>

Вам не обязательно полагаться на автоматическое отображение. Например, действия, которые могут привести к отображению разных шаблонов, будут использовать ручные методы отображения:

def search
  @results = Search.find(params[:query])
  case @results.count
    when 0 then render action: "no_results"
    when 1 then render action: "show"
    when 2..10 then render action: "show_many"
  end
end

Подробнее о написании шаблонов ERB и Builder см. в ActionView::Base.

Перенаправления

Перенаправления используются для перехода от одного действия к другому. Например, после действия create , которое сохраняет запись блога в базу данных, мы можем показать пользователю новую запись. Поскольку мы следуем принципу DRY (Don't Repeat Yourself), мы будем повторно использовать (и перенаправлять на) действие show, которое мы предполагаем уже создано. Код может выглядеть так:

def create
  @entry = Entry.new(params[:entry])
  if @entry.save
    # The entry was saved correctly, redirect to show
    redirect_to action: 'show', id: @entry.id
  else
    # things didn't go so well, do something else
  end
end

В этом случае после сохранения новой записи в базу данных пользователь перенаправляется на метод show, который затем выполняется. Обратите внимание, что это внешнее перенаправление на уровне HTTP, которое заставит браузер выполнить второй запрос (GET к действию show), а не внутреннее перенаправление, которое вызовет как «create», так и «show» в рамках одного запроса.

Узнайте больше о redirect_to и доступных вариантах в ActionController::Redirecting.

Вызов нескольких перенаправлений или отображений

Действие может содержать только одно отображение или одно перенаправление. Попытка сделать это снова приведет к ошибке DoubleRenderError:

def do_something
  redirect_to action: "elsewhere"
  render action: "overthere" # raises DoubleRenderError
end

Если вам нужно перенаправление при выполнении условия, убедитесь, что добавили «and return», чтобы остановить выполнение.

def do_something
  redirect_to(action: "elsewhere") and return if monkeys.nil?
  render action: "overthere" # won't be called if monkeys is nil
end

Константы

MODULES
PROTECTED_IVARS

Определяют некоторые внутренние переменные, которые не должны распространяться в представление.

Публичные методы класса

protected_instance_variables() Показать исходный код
# File actionpack/lib/action_controller/base.rb, line 261
def self.protected_instance_variables
  PROTECTED_IVARS
end
without_modules(*modules) Показать исходный код

Короткая вспомогательная функция, которая возвращает все модули, включенные в ActionController::Base, за исключением переданных в качестве аргументов:

class MetalController
  ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
    include left
  end
end

Это обеспечивает лучший контроль над тем, что нужно исключить, и упрощает создание базового класса контроллера вместо ручного перечисления необходимых модулей.

# File actionpack/lib/action_controller/base.rb, line 195
def self.without_modules(*modules)
  modules = modules.map do |m|
    m.is_a?(Symbol) ? ActionController.const_get(m) : m
  end

  MODULES - modules
end

Публичные методы экземпляра

request() Показать исходный код

Возвращает экземпляр ActionDispatch::Request, который представляет текущий запрос.

# File actionpack/lib/action_controller/base.rb, line 177
    
response() Показать исходный код

Возвращает ActionDispatch::Response, представляющий текущий ответ.

# File actionpack/lib/action_controller/base.rb, line 183
    

© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API