Когда мы используем маршрутизацию ресурсов в Rails (пути типа «/ blogs / new» или «/ blogs / 2 / edit»), мы часто используем переменные пути, такие как new_blogs_path
Но когда мы работаем в Javascript, мы должны жестко закодировать пути, то есть «/ blog / new». В этой статье мы расскажем о JsRoutes, удивительном драгоценном камне, который позволяет нам использовать аналогичный набор помощников URL в нашем коде Javascript.
Зачем нам нужны JsRoutes?
Идея состоит в том, что вам не нужно создавать URL-адреса вручную в Javascript, если библиотека может сделать это за вас! Это становится очевидным, как только вы начинаете делать вложенные маршруты. Например, рассмотрим следующую конфигурацию маршрутизации:
resources :posts do
resources :comments
end
Если мы хотим, чтобы путь редактировал комментарий с идентификатором 4, который связан с сообщением с идентификатором 1, он дает «/ posts / 1 / comments / 4 / edit», что является полным глотком. Намного проще использовать URL-помощники, предоставляемые Rails, чем создавать эту строку в нашем Javascript.
Настроить
Если в Rails работает конвейер ресурсов, настроить JsRoutes невероятно просто. Просто добавьте следующее в Gemfile:
gem "js-routes"
Затем запустите bundle install
В любом файле Javascript (часто в application.js
//= require js-routes
Если, следуя этой статье, вы обнаружите, что JsRoutes не загружается в ваш Javascript, вам может потребоваться очистить кэш конвейера ресурсов:
rake tmp:cache:clear
Теперь у вас должен быть готов JsRoutes. Давайте прыгнем и посмотрим на некоторые основы.
Основы
Скажем, мы добавили новый ресурсный маршрут в config/routes.rb
resources :posts
Каждый пост имеет поле заголовка и поле контента. В PostsController
class PostsController < ApplicationController
...
def create
@post = Post.new(:title => params[:title],
:content => params[:content])
@post.save
respond_to do |format| do
#probably should render something more sensible in a
#real application.
format.json { render :json => "{}"}
end
end
...
end
Обратите внимание, что мы не возвращаем никаких ошибок, возникающих при сохранении сообщения, как части ответа. На практике это плохая идея, но мы позволим ей сдвинуться с места, поскольку этот пример на самом деле не касается данных, возвращаемых с сервера. В Javascript предположим, что у нас есть хорошая форма для создания нового сообщения, и мы хотим отправить эту форму с помощью AJAX. Разбить JQuery:
$.post(path, {title: $("#title_field").val(), content: $("#content_field").val()}, function(response) {
//do something w/ the response
});
Но как мы можем получить значение path
Вот где JsRoutes вступает в игру:
var path = Routes.posts_path({format: "json"});
Если вы попытаетесь console.log
"/paths.json"
Может быть немного трудно вспомнить, какие вызовы JsRoutes соответствуют каким действиям в контроллере (хотя имена почти совпадают с соответствующими помощниками Rails). Один из способов получить быстрое повышение квалификации — добавить:
console.log(Routes)
в один из ваших файлов Javascript и проверьте вывод. Другой способ с этим удобным столом:
Контроллер # Действие | Вызов функции JsRoutes |
---|---|
сообщения # индекс | Routes.posts_path () |
сообщения # новых | Routes.new_post_path () |
сообщения # создать | Routes.posts_path () |
сообщения # показать | Routes.post_path (ID) |
сообщения # редактировать | Routes.edit_post_path (ID) |
сообщения # обновление | Routes.post_path (ID) |
сообщения # уничтожить | Routes.post_path (ID) |
Обратите внимание, что JsRoutes состоит из вызовов функций, что означает, в Javascript, что мы должны иметь круглые скобки вызова (т.е. «()»), независимо от того, есть ли у нас аргумент «id». Также обратите внимание, что некоторые пути для разных действий одинаковы (например, пути для posts # index и posts # create). Для них правильное действие вызывается на основе используемого глагола HTTP (например, GET vs. POST).
Вложенные маршруты
Хорошо, давайте посмотрим, как обрабатывать вложенные маршруты с помощью JsRoutes. К счастью, если у вас есть опыт работы с URL-помощниками Rails, вы будете чувствовать себя как дома. Допустим, у нас есть эта конфигурация маршрута:
resources :posts do
resources :comments
end
Помощники по URL немного более многословны, но идеи те же:
Контроллер # Действие | Вызов функции JsRoutes |
---|---|
комментарии # индекс | Routes.post_comments_path (post_id) |
комментарии # новый | Routes.new_post_comment_path (post_id) |
комментарии # создать | Routes.post_comments_path (post_id) |
комментарии # показать | Routes.post_comment_path (post_id, comment_id) |
комментарии # редактировать | Routes.edit_post_comment_path (post_id, comment_id) |
комментарии # обновление | Routes.update_post_comment_path (post_id) |
комментарии # уничтожить | Routes.post_path (ID) |
Как правило, если вы передаете идентификатор для определенного ресурса, используйте единственную форму этого ресурса (например, «post»), а если вы не передаете идентификатор, используйте форму множественного числа (например, «comments»).
Магия «to_param»
Если в вашем приложении есть URL-адреса, такие как «/ post / 138», SEO может быть немного сложным, потому что из URL невозможно сообщить какую-либо информацию (например, заголовок или контент) о публикации, на которую ссылается URL. Вот почему Rails дает нам to_param
Мы можем увидеть это в действии в нашей модели Post:
class Post < ActiveRecord::Base
#...
#maybe verify uniqueness of title
def to_param
title.gsub(/ /, '_').downcase
end
#...
end
Если у нас есть пост с заголовком «JSRoutes is Awesome», то теперь мы можем ссылаться на этот пост как /posts/jsroutes_is_awesome
JsRoutes позволяет вам использовать «to_param» для генерации путей. Давайте рассмотрим пример с плоским ресурсом:
var path = Routes.post_path({to_param: "jsroutes_is_awesome"}, {format: "json"});
Это создает путь /posts/jsroutes_is_awesome.json
Это означает, что если у вас есть копия заголовка поста в Javascript, вам придется переопределить логику to_param
Конфигурирование JsRoutes
Существует несколько способов настройки JsRoutes, которые могут быть весьма полезны для конкретных ситуаций. Вы можете управлять конфигурацией через инициализатор, поэтому создайте новую в config / initializer / jsroutes.rb . Вот как работает общий формат инициализатора:
JsRoutes.setup do |config|
config.option = value
end
По сути, у вас есть куча возможных опций конфигурации, которые вы можете установить. Давайте посмотрим на некоторые из них. Одним из самых полезных для меня было:
JsRoutes.setup do |config|
config.default_url_options = {:format => "json"}
end
Для этого нужны все помощники по URL и по умолчанию добавляется «.json» в конце. Если вы пишете одностраничное приложение, в котором большинство ваших HTTP-запросов фактически запускаются Javascript, вы почти никогда не загружаете HTML, так как большая часть ваших данных будет в JSON. В этом случае имеет смысл установить формат по умолчанию JSON.
Другой важный параметр конфигурации URL :exclude
JsRoutes.setup do |config|
config.default_url_options = {:exclude => [/^admin$/]}
end
Это исключит любые связанные с администратором URL-адреса из объекта Route, переданного коду Javascript. Идея заключается в том, что вы не хотите, чтобы все URL-адреса в вашем проекте были доступны клиенту (однако при разработке приложения рекомендуется предположить, что у злоумышленника есть этот список путей). Таким образом, с помощью ключа exclude
Скажем, вам всегда нужны полные пути (например, «http://example.com/posts»), а не локальные (например, «/ posts»). Это тоже легко:
JsRoutes.setup do |config|
config.prefix = "http://example.com"
end
Обратите внимание, что нет косой черты.
Завершение
Написание кода Rails в современном, управляемом Javascript вебе требует большого умственного переключения контекста. С JsRoutes, по крайней мере, вам не нужно переосмысливать способ обработки путей, когда вы переключаетесь на внешние части вашей кодовой базы.