Статьи

Rails URL Helpers в Javascript с помощью JsRoutes

Снимок экрана 2015-01-15 12.39.58

Когда мы используем маршрутизацию ресурсов в 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, по крайней мере, вам не нужно переосмысливать способ обработки путей, когда вы переключаетесь на внешние части вашей кодовой базы.