Создание маршрутов в Discourse и отображение данных

Со временем Discourse стал более сложным, и новичкам может быть трудно понять, как данные передаются от серверного приложения на Ruby on Rails к клиентскому приложению на Ember.js.

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

Сначала URL-адреса

Я всегда предпочитаю начинать думать о функциях в терминах URL-адресов для доступа к ним. Например, предположим, что мы хотим создать административную функцию, которая показывала бы последний перекус, который я съел во время работы над Discourse. Подходящим URL-адресом для этого был бы /admin/snack.

В этом случае:

  • При посещении /admin/snack в вашем браузере должен отображаться перекус с использованием «полного стека», другими словами, загрузится приложение Ember, и оно запросит данные, необходимые для отображения перекуса.

  • При посещении /admin/snack.json должен возвращаться JSON-данные самого перекуса.

Серверная часть (Ruby on Rails)

Начнем с создания нового контроллера для перекуса.

app/controllers/admin/snack_controller.rb

class Admin::SnackController < Admin::AdminController
  def index
    render json: { name: "donut", description: "delicious!" }
  end
end

В этом случае мы наследуемся от Admin::AdminController, чтобы получить все проверки безопасности, гарантирующие, что пользователь, просматривающий контроллер, является администратором. Нам нужно сделать еще одну вещь, прежде чем мы сможем получить доступ к нашему контроллеру, — добавить строку в config/routes.rb:

Найдите блок, который выглядит так:

namespace :admin, constraints: StaffConstraint.new do
  # много всего
end

И добавьте внутрь него эту строку:

get 'snack' => 'snack#index'

После этого вы сможете посетить /admin/snack.json в своем браузере и увидите JSON для перекуса! Наш API перекусов, похоже, работает :candy:

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

Клиентская часть (Ember.js)

Если вы откроете свой браузер и посетите /admin/snack (без .json), вы увидите, что Discourse пишет: «Ой! Страница не существует». Это потому, что в нашем клиентском приложении Ember нет ничего, что могло бы ответить на этот маршрут. Давайте добавим шаблон .gjs, чтобы показать наш перекус:

app/assets/javascripts/admin/templates/snack.gjs

<template>
  <h1>{{@controller.model.name}}</h1>

  <hr />

  <p>{{@controller.model.description}}</p>
</template>

И, как и на стороне Rails API, нам нужно настроить маршрут. Откройте файл app/assets/javascripts/admin/routes/admin-route-map.js и найдите метод export default function(). Добавьте следующую строку:

this.route("snack");

У нас осталось сделать еще одну вещь в мире Ember — заставить приложение Ember выполнить AJAX-запрос для получения нашего JSON с сервера. Давайте создадим последний файл. Это будет Ember Route. Его функция model() будет вызвана при входе в маршрут, поэтому мы сделаем наш вызов ajax внутри неё:

app/assets/javascripts/admin/routes/admin-snack.js

import { ajax } from "discourse/lib/ajax";

export default Ember.Route.extend({
  model() {
    return ajax("/admin/snack.json");
  },
});

Теперь вы можете открыть свой браузер по адресу /admin/snack, и вы должны увидеть детали перекуса, отображенные на странице!

Резюме

  • Открытие браузера по адресу /admin/snack запускает приложение Ember.

  • Маршрутизатор приложения Ember говорит, что snack должен быть маршрутом.

  • Ember.Route для snack выполняет AJAX-запрос к /admin/snack.json.

  • Маршрутизатор приложения Rails говорит, что это должен быть admin_snack controller.

  • admin_snack_controller возвращает JSON.

  • Приложение Ember получает JSON и рендерит шаблон .gjs.

Куда двигаться дальше

Я написал продолжение учебника о том, как добавить компонент Ember в Discourse.


Этот документ находится под контролем версий — предложите изменения на GitHub.

46 лайков