Вот как думать об этом, с самого начала:
1) Одно и единственное, что ваше приложение делает реагировать на HTTP-запросы.
Наиболее типичные виды запросов являются:
Существуют также другие виды HTTP-запросов, самое главное PUT, PATCH и DELETE. Rails следует за шаблоном REST, что означает, что он присваивает определенные значения этим HTTP-глаголам.
2) Когда какой-либо запрос поступает в ваше приложение, он должен быть перенаправлен на действие контроллера.
Ваш routes.rb
файл представляет собой набор инструкций для Rails Router (ActionDispatch), который сообщает маршрутизатору, куда отправлять запросы.«Стандарт» рельсы ресурса дается как ярлык, например:
resources :things
Это означает следующее:
GET /things => things#index
GET /things/:id => things#show
GET /things/new => things#new
GET /things/edit/:id => things#edit
POST /things => things#create
PUT /things/:id => things#update
DELETE /things/:id => things#destroy
Они считаются стандартными RESTful действия - ничто иное не установлено вашим resources :things
декларации , Итак, если вы хотите, чтобы контроллер выполнял другие нестандартные действия, вы должны добавить их вручную.
Если вы хотите, чтобы выполнить действие на конкретную запись, лучший способ заключается в использовании:
resources :things do
member do
get 'vote_up'
end
end
Это говорит маршрутизатору, что если кто-то делает запрос GET к /things/123/vote_up
, что он должен вызвать в ThingsController
vote_up
действие.
Все это подробно изложено в Rails Guide, вы должны прочитать все это.
3) Задача вашего диспетчера - отправить ответ на запрос.
Обычно это означает что-то вроде загрузки записи из базы данных и визуализации представления для этой записи.
Каждое действие контроллера завершается отправкой ответа обратно на входящий запрос. Этот ответ может быть либо вызовом render
, что означает отправку некоторых данных в некотором формате - или вызов redirect
- который в основном делает новый запрос для вас, и поэтому вы получаете ответ от этого другого запроса.
В Rails перенаправление эффективно отправляет запрос на другое действие контроллера.
Render call отправляет данные в ответ на запрос.
При вызове render :new
, это ярлык render :template => :new
, который загружает шаблон app/views/things/new.html.erb
(или любой другой), передает его данные из контроллера (обычно ваши переменные экземпляра) и оценивает это с помощью языка шаблонов (ERB, HAML и т. д.). Это приводит к большой строке HTML, которую контроллер затем передает в браузер.
Хотите видеть это в себе? Попробуйте окончание контроллер с render :text => 'Hello World'
, или даже:
render :inline => '<!DOCTYPE html><head><title>Inline Wow!</title></head><body>Mind blown.</body></html>'
Посмотрите, что происходит.
При ответе (отрисовке) вы можете отправлять «обычные» HTML-шаблоны, имея в своем распоряжении всю ценность страницы (head, body и т. Д.) Или частичную, которая используется Ajax. Вы также можете отправлять необработанные данные, такие как JSON или XML. На самом деле это всего лишь текст, и в зависимости от содержимого этого текста (и заголовков HTTP, которые приходят с ним) браузер, сценарий или клиентское приложение обрабатывают его соответствующим образом.
Опять же, см. Rails Guide.
4) Когда запрос сделан браузером, вы, вероятно, захотите отправить обратно HTML. Если запрос сделан Ajax, вы, вероятно, захотите отправить обратно JSON.
В случае пользовательского действия, такого как vote_up
, вы можете не захотеть показать шаблон вообще, а просто перенаправить. Итак, у вас может быть что-то вроде этого:
ThingsController < ApplicationController
def vote_up
@thing = Thing.find(params[:id])
@thing.vote_up
redirect_to @thing
end
end
Теперь одно из преимуществ маршрутизатора - это предоставить вам URL-адреса. Если вы создали маршрут и действия, как показано выше, на странице «показать вещь» вы могли бы иметь URL вроде этого:
link_to 'Vote up this thing!', vote_up_thing_path(@thing)
Это создало бы ссылку на things/123/vote_up
, и если кто-то нажал на него будет запускать код в действии vote_up
на ThingsController
, а затем перенаправлять обратно в представление show thing.
5) Ваши шаблоны отправляют сообщения контроллерам, используя ссылки и формы. Ссылки делают запросы GET, формы обрабатывают запросы POST.
Если вы хотите начать с запросов AJAX, все в порядке. В этом случае вам просто нужно сделать запрос в Javascript и обработать ответ. Так, например, вы могли бы поставить что-то вроде этого в шаблоне:
= link_to 'Vote up this thing', vote_up_thing_path(@thing), :id => 'vote-up-button'
Тогда в Javascript (с JQuery) вы могли бы иметь такую функцию:
$(function(){
$('a#vote-up-button').click(function(event){
event.preventDefault();
$.ajax({
url: this.attr('href'),
type: 'GET',
success: function(){...},
error: function(){...}
});
});
});
В этом случае JQuery Ajax метод просто делает запрос на получение, а затем выполняет функцию обратного вызова на основе полученного ответа.
6) Структура вашего контроллера/маршрута не влияет на какие запросы вы можете сделать, только какое действие будет реагировать на то, какой метод HTTP на каком URL-адресе.
Что вы делаете внутри вашего действия контроллера определяет, являетесь ли вы готовы ответить на яваскрипт или HTML запросы и т.д.
Хотя рельсы, конечно, иметь возможность обрабатывать несколько форматов запросов в одном действии контроллера, используя блок respond_to
, в практическом отношении я нахожу, что все работает намного плавно, когда вы выбираете, чтобы маршруты отвечали только на один или другой формат.
IE: Я бы сделал ваши обычные запросы на загрузку страницы (индекс, показать, новый, отредактировал) только HTML-запросы, а затем я сделаю любые дополнительные действия AJAX, которые вы хотите добавить, только Javascript - т.е. они отвечают с JSON вместо HTML. Конечно, вам не обязательно это делать, но ваша жизнь будет легче, если вы это сделаете.
Надеюсь, это даст вам более четкое представление о том, что происходит в вашем приложении. Добро пожаловать в Rails, вы присоединяетесь к большому сообществу!
почтовый индекс из файла 'routes.rb'. – ole