-
Notifications
You must be signed in to change notification settings - Fork 0
/
working-with-javascript-in-rails.html
390 lines (366 loc) · 38.1 KB
/
working-with-javascript-in-rails.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#">
<head>
<meta charset="utf-8">
<meta content="Ruby on Rails, Ruby, Rails, Rails 3, Rails 4, Rails 5, Rails 6, Rails 6.0, Rails 6.1, Rails 7.0, Rails 7.1 руководство, начинающим, самоучитель, manual, мануал, справочник, учебник, примеры, Руби, рельсы" name="keywords"/>
<meta content="Ruby on Rails руководства, учебники, статьи на русском языке" name="description"/>
<meta content="website" property="og:type"/>
<meta content="Rusrails: Работа с JavaScript в Rails" property="og:title"/>
<meta content="Ruby on Rails руководства, учебники, статьи на русском языке" property="og:description"/>
<meta content="http://localhost:3000/working-with-javascript-in-rails" property="og:url"/>
<meta content="http://rusrails.ru/assets/rusrails.png" property="og:image"/>
<title>
Rusrails: Работа с JavaScript в Rails
</title>
<link rel="stylesheet" href="/assets/application-f9dfa6ce7fa871006d478e422639671663284ddaa3126cf81ddfe371ac3533c4.css" />
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="brand" href="/"></a>
<ul class="nav pull-right top-menu">
<li>
<a href="/">Главная</a>
</li>
<li class="dropdown">
<a class="index-popover" href="#">
Содержание
<b class="caret"></b>
</a> <div class="index-popover-content hide">
<ul><li><p><strong>С чего начать?</strong></p><ul><li><a href="/getting-started">Rails для начинающих</a>
</li></ul></li><li><p><strong>Модели</strong></p><ul><li><a href="/active-record-basics">Основы Active Record</a>
</li><li><a href="/active-record-migrations">Миграции Active Record</a>
</li><li><a href="/active-record-validations">Валидации Active Record</a>
</li><li><a href="/active-record-callbacks">Колбэки Active Record</a>
</li><li><a href="/active-record-associations">Связи (ассоциации) Active Record</a>
</li><li><a href="/active-record-querying">Интерфейс запросов Active Record</a>
</li><li><a href="/active-model-basics">Основы Active Model</a>
</li></ul></li><li><p><strong>Вью</strong></p><ul><li><a href="/action-view-overview">Обзор Action View</a>
</li><li><a href="/layouts-and-rendering">Макеты и рендеринг в Rails</a>
</li><li><a href="/action-view-helpers">Хелперы Action View</a>
</li><li><a href="/form-helpers">Хелперы форм в Action View</a>
</li></ul></li><li><p><strong>Контроллеры</strong></p><ul><li><a href="/action-controller-overview">Обзор Action Controller</a>
</li><li><a href="/routing">Роутинг в Rails</a>
</li></ul></li><li><p><strong>Другие компоненты</strong></p><ul><li><a href="/active-support-core-extensions">Расширения ядра Active Support</a>
</li><li><a href="/action-mailer-basics">Основы Action Mailer</a>
</li><li><a href="/action-mailbox-basics">Основы Action Mailbox</a>
</li><li><a href="/action-text-overview">Обзор Action Text</a>
</li><li><a href="/active_job_basics">Основы Active Job</a>
</li><li><a href="/active_storage_overview">Обзор Active Storage</a>
</li><li><a href="/action-cable-overview">Обзор Action Cable</a>
</li></ul></li><li><p><strong>Копаем глубже</strong></p><ul><li><a href="/i18n">API интернационализации Rails (I18n)</a>
</li><li><a href="/testing">Тестирование приложений на Rails</a>
</li><li><a href="/security">Безопасность приложений на Rails</a>
</li><li><a href="/error-reporting">Отчет об ошибках в приложениях Rails</a>
</li><li><a href="/debugging-rails-applications">Отладка приложений на Rails</a>
</li></ul></li></ul><p>next_column</p><ul><li><p><strong>Копаем глубже</strong></p><ul><li><a href="/configuring">Конфигурирование приложений на Rails</a>
</li><li><a href="/command-line">Командная строка Rails</a>
</li><li><a href="/asset-pipeline">Asset Pipeline</a>
</li><li><a href="/working-with-javascript-in-rails">Работа с JavaScript в Rails</a>
</li><li><a href="/initialization">Процесс инициализации в Rails</a>
</li><li><a href="/autoloading-and-reloading-constants">Автозагрузка и перезагрузка констант</a>
</li><li><a href="/caching-with-rails">Кэширование с Rails: Обзор</a>
</li><li><a href="/active-support-instrumentation">Инструментарий Active Support</a>
</li><li><a href="/api-app">Использование Rails для API-приложений</a>
</li><li><a href="/active-record-postgresql">Active Record для PostgreSQL</a>
</li><li><a href="/active-record-multiple-databases">Несколько баз данных с Active Record</a>
</li><li><a href="/active-record-encryption">Шифрование Active Record</a>
</li></ul></li><li><p><strong>Расширяем Rails</strong></p><ul><li><a href="/plugins">Основы создания плагинов Rails</a>
</li><li><a href="/rails-on-rack">Rails on Rack</a>
</li><li><a href="/generators">Создание и настройка генераторов и шаблонов Rails</a>
</li><li><a href="/engines">Engine для начинающих</a>
</li><li><a href="/threading_and_code_execution">Треды и выполнение кода в Rails</a>
</li><li><a href="/rails-application-templates">Шаблоны приложения Rails</a>
</li></ul></li><li><p><strong>Вносим вклад в Ruby on Rails</strong></p><ul><li><a href="/contributing_to_ruby_on_rails">Вносим вклад в Ruby on Rails</a>
</li><li><a href="/api_documentation_guidelines">Рекомендации по документированию API</a>
</li><li><a href="/ruby_on_rails_guides_guidelines">Рекомендации для руководств по Ruby on Rails</a>
</li><li><a href="/development_dependencies_install">Установка зависимостей для разработки</a>
</li><li><a href="/maintenance-policy">Политика поддержки (версий)</a>
</li></ul></li><li><p><strong>Заметки о релизах</strong></p><ul><li><a href="/upgrading-ruby-on-rails">Апгрейд Ruby on Rails</a>
</li><li><a href="/7_2_release_notes">Версия 7.2 - ?</a>
</li><li><a href="/7_1_release_notes">Версия 7.1 - Октябрь 2023</a>
</li><li><a href="/7_0_release_notes">Версия 7.0 - Декабрь 2021</a>
</li><li><a href="/6_1_release_notes">Версия 6.1 - Декабрь 2020</a>
</li><li><a href="/6_0_release_notes">Версия 6.0 - Август 2019</a>
</li></ul></li></ul>
</div>
</li>
<li>
<a href="/search">Поиск</a>
</li>
<li>
<a target="blank" href="http://api.rusrails.ru">Ruby & Rails API</a>
</li>
</ul>
</div>
</div>
</div>
<div class="content-wrapper">
<div class="container-fluid">
<div class="row-fluid">
<div class="span3 pull-right">
<div class="well social">
<h4>Принимаем пожелания и пул-реквесты!</h4>
<iframe allowtransparency="true" frameborder="0" height="30" src="http://ghbtns.com/github-btn.html?user=rusrails&repo=rusrails&type=watch&count=true&size=large" width="180"></iframe>
</div>
<div class="well menu">
<ul class="nav nav-list">
<li>
<h4>
<a href="#import-maps">1. Карты импорта</a>
</h4> </li>
<li>
<h5>
<a href="#ustanovka-importmap-rails">1.1. Установка importmap-rails</a>
</h5> </li>
<li>
<h5>
<a href="#dobavlenie-paketov-npm-s-pomoschyu-importmap-rails">1.2. Добавление пакетов NPM с помощью importmap-rails</a>
</h5> </li>
<li>
<h4>
<a href="#dobavlenie-paketov-npm-s-pomoschyu-sborschikov-javascript">2. Добавление пакетов NPM с помощью сборщиков JavaScript</a>
</h4> </li>
<li>
<h5>
<a href="#ustanovka-node-js-i-yarn">2.1. Установка Node.js и Yarn</a>
</h5> </li>
<li>
<h4>
<a href="#vybor-mezhdu-kartami-importa-i-sborschikom-javascript">3. Выбор между картами импорта и сборщиком JavaScript</a>
</h4> </li>
<li>
<h4>
<a href="#turbo">4. Turbo</a>
</h4> </li>
<li>
<h5>
<a href="#turbo-drive">4.1. Turbo Drive</a>
</h5> </li>
<li>
<h5>
<a href="#turbo-frames">4.2. Turbo Frames</a>
</h5> </li>
<li>
<h5>
<a href="#turbo-streams">4.3. Turbo Streams</a>
</h5> </li>
<li>
<h4>
<a href="#zameny-dlya-funktsionala-rails-ujs">5. Замены для функционала Rails/UJS</a>
</h4> </li>
<li>
<h5>
<a href="#metod">5.1. Метод</a>
</h5> </li>
<li>
<h5>
<a href="#podtverzhdeniya">5.2. Подтверждения</a>
</h5> </li>
</ul>
</div>
<div class="well banner300 banner">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- sidebar rusrails -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:600px"
data-ad-client="ca-pub-7764391801669990"
data-ad-slot="6089520660"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
<div class="span9 content pull-left">
<div class="banner">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- top rusrails -->
<ins class="adsbygoogle"
style="display:inline-block;width:980px;height:120px"
data-ad-client="ca-pub-7764391801669990"
data-ad-slot="4891989065"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
<h2 id='rabota-s-javascript-v-rails' class='inside_page_header'> Работа с JavaScript в Rails</h2><p>Это руководство раскрывает опции для интегрирования функционала JavaScript в ваше приложение Rails, включая опции с использованием внешних пакетов JavaScript, а также как использовать Turbo с Rails.</p><p>После прочтения этого руководства вы узнаете:</p><ul><li>Как использовать Rails без необходимости Node.js, Yarn или сборщика JavaScript.
</li><li>Как создать новое приложение Rails с помощью карт импорта, esbuild, rollup или webpack, чтобы собрать свой JavaScript.
</li><li>Что такое Turbo, и как его использовать.
</li><li>Как использовать хелперы Turbo HTML, предоставленные Rails.
</li></ul>
<hr>
<h3 id='import-maps' class='inside_page_header'><a href="#import-maps">1.</a> Карты импорта</h3><p><a href="https://github.com/rails/importmap-rails">Карты импорта</a> позволяют импортировать модули JavaScript с помощью логических имен, которые направляют к версионированным файлам непосредственно из браузера. Карты импорта включены по умолчанию, начиная с Rails 7, позволяя каждому создавать современный приложения JavaScript с помощью большинства пакетов NPM без необходимости транспиляции или сборки.</p><p>Приложениям, использующим карты импорта, для функционирования не нужен <a href="https://nodejs.org/en/">Node.js</a> или <a href="https://yarnpkg.com/">Yarn</a>. Если планируете использовать Rails с <code>importmap-rails</code> для управления зависимостями JavaScript, не нужно устанавливать Node.js или Yarn.</p><p>При использовании карт импорта не нужен отдельный процесс для сборки, просто запустите свой сервер с помощью <code>bin/rails server</code>, и все заработает.</p><h4 id='ustanovka-importmap-rails' class='inside_page_header'><a href="#ustanovka-importmap-rails">1.1.</a> Установка importmap-rails</h4><p>Importmap для Rails автоматически включен в Rails 7+ для новых приложений, но его также можно установить вручную в существующие приложения:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span>bin/bundle add importmap-rails
</code></pre>
</div>
<p>Запустите задачу установки:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">bin/rails </span>importmap:install
</code></pre>
</div>
<h4 id='dobavlenie-paketov-npm-s-pomoschyu-importmap-rails' class='inside_page_header'><a href="#dobavlenie-paketov-npm-s-pomoschyu-importmap-rails">1.2.</a> Добавление пакетов NPM с помощью importmap-rails</h4><p>Чтобы добавить новые пакеты в приложение с картой импорта, запустите команду <code>bin/importmap pin</code> из терминала:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span>bin/importmap pin react react-dom
</code></pre>
</div>
<p>Затем импортируйте пакет в <code>application.js</code> как обычно:</p><div class="code_container">
<pre><code class="highlight javascript"><span class="k">import</span> <span class="nx">React</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span>
<span class="k">import</span> <span class="nx">ReactDOM</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-dom</span><span class="dl">"</span>
</code></pre>
</div>
<h3 id='dobavlenie-paketov-npm-s-pomoschyu-sborschikov-javascript' class='inside_page_header'><a href="#dobavlenie-paketov-npm-s-pomoschyu-sborschikov-javascript">2.</a> Добавление пакетов NPM с помощью сборщиков JavaScript</h3><p>Карты импорта по умолчанию в новом приложении Rails, но если предпочитаете традиционную сборку JavaScript, можете создать новые приложения Rails с <a href="https://esbuild.github.io/">esbuild</a>, <a href="https://webpack.js.org/">webpack</a> или <a href="https://rollupjs.org/guide/en/">rollup.js</a> на ваш выбор.</p><p>Для использования сборщика вместо карт импорта в новом приложении Rails, передайте опцию <code>—javascript</code> или <code>-j</code> в <code>rails new</code>:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">rails </span>new my_new_app <span class="nt">--javascript</span><span class="o">=</span>webpack
<span class="go">ИЛИ
</span><span class="gp">$</span><span class="w"> </span><span class="nb">rails </span>new my_new_app <span class="nt">-j</span> webpack
</code></pre>
</div>
<p>Каждая из опций сборки поставляется с простой конфигурацией и интеграцией в конвейер ресурсов с помощью гема <a href="https://github.com/rails/jsbundling-rails">jsbundling-rails</a>.</p><p>При использовании опции сборки, используйте <code>bin/dev</code> для запуска сервера Rails и создания JavaScript для development.</p><h4 id='ustanovka-node-js-i-yarn' class='inside_page_header'><a href="#ustanovka-node-js-i-yarn">2.1.</a> Установка Node.js и Yarn</h4><p>Если вы используете сборщик JavaScript в своем приложении Rails, должны быть установлены Node.js и Yarn.</p><p>Инструкции по установке можно найти на <a href="https://nodejs.org/en/download/">веб-сайте Node.js</a>, а проверить, что он установлен корректно можно с помощью следующей команды:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">node</span> <span class="nt">--version</span>
</code></pre>
</div>
<p>Должна быть выведена версия вашего Node.js runtime. Убедитесь, что она выше, чем <code>8.16.0</code>.</p><p>Чтобы установить Yarn, следуйте инструкциям по установке на <a href="https://classic.yarnpkg.com/en/docs/install">веб-сайте Yarn</a>. Запуск этой команды должен вывести версию Yarn:</p><div class="code_container">
<pre><code class="highlight console"><span class="gp">$</span><span class="w"> </span><span class="nb">yarn</span> <span class="nt">--version</span>
</code></pre>
</div>
<p>Если она сообщит что-то вроде <code>1.22.0</code>, Yarn был установлен корректно.</p><h3 id='vybor-mezhdu-kartami-importa-i-sborschikom-javascript' class='inside_page_header'><a href="#vybor-mezhdu-kartami-importa-i-sborschikom-javascript">3.</a> Выбор между картами импорта и сборщиком JavaScript</h3><p>Когда создаете новое приложение Rails, нужно выбрать между картами импорта и решением со сборкой JavaScript. У каждого приложения имеются разные требования, и вам следует тщательно рассмотреть эти требования перед выбором варианта JavaScript, так как миграция от одной опции к другой может быть затратной по времени для больших, сложных приложений.</p><p>Карты импорта являются опцией по умолчанию, так как команда Rails верит в потенциал карт импорта для уменьшения сложности, улучшения опыта разработки и улучшения производительности.</p><p>Для многих приложений, особенно тех, что в основном полагаются на стек <a href="https://hotwired.dev/">Hotwire</a> для нужд JavaScript, карты импорта будут правильной опцией в долгосрочном плане. О причинах, лежащих в основе решения сделать карты импорта опцией по умолчанию в Rails 7, можно прочитать <a href="https://world.hey.com/dhh/rails-7-will-have-three-great-answers-to-javascript-in-2021-8d68191b">здесь</a>.</p><p>Другим приложениям может все еще быть необходим традиционный сборщик JavaScript. Требования, сигнализирующие, что следует выбрать традиционный сборщик, включают:</p><ul><li>Если ваш код включает шаг транспиляции, такой как JSX или TypeScript.
</li><li>Если вам нужны библиотеки JavaScript: включающие CSS, или иным образом полагающиеся на <a href="https://webpack.js.org/loaders/">загрузчики Webpack</a>.
</li><li>Если вы абсолютно уверены, что вам необходим <a href="https://webpack.js.org/guides/tree-shaking/">tree-shaking</a>.
</li><li>Если вы установили Bootstrap, Bulma, PostCSS или Dart CSS с помощью <a href="https://github.com/rails/cssbundling-rails">гема cssbundling-rails</a>. Все опции, предоставляемые этим гем, кроме Tailwind, автоматически установят <code>esbuild</code>, если не указать другую опцию в <code>rails new</code>.
</li></ul><h3 id='turbo' class='inside_page_header'><a href="#turbo">4.</a> Turbo</h3><p>Выберите ли вы карты импорта или традиционный сборщик, Rails поставляется с <a href="https://turbo.hotwired.dev/">Turbo</a> для ускорения приложения, значительно уменьшая объем JavaScript, который нужно было бы написать.</p><p>Turbo позволяет серверу доставлять непосредственно HTML, в качестве альтернативы превалирующим фронтенд фреймворкам, что уменьшает серверную часть вашего приложения Rails почти до JSON API.</p><h4 id='turbo-drive' class='inside_page_header'><a href="#turbo-drive">4.1.</a> Turbo Drive</h4><p><a href="https://turbo.hotwired.dev/handbook/drive">Turbo Drive</a> ускоряет загрузки страниц, избегая закрытия и пересоздания на каждом запросе навигации. Turbo Drive это улучшение и замена Turbolinks.</p><h4 id='turbo-frames' class='inside_page_header'><a href="#turbo-frames">4.2.</a> Turbo Frames</h4><p><a href="https://turbo.hotwired.dev/handbook/frames">Turbo Frames</a> позволяет предопределенным частям страницы быть обновленными по запросу, не влияя на остальное содержимое страницы.</p><p>Turbo Frames можно запросто использовать для встроенного редактирования без какого-либо пользовательского JavaScript, ленивой загрузки содержимого или создания интерфейса с вкладками, создаваемыми на сервере.</p><p>Rails предоставляет хелперы HTML для упрощения использования Turbo Frames с помощью гема <a href="https://github.com/hotwired/turbo-rails">turbo-rails</a>.</p><p>Используя этот гем, можно добавить Turbo Frame в ваше приложение с помощью хелпера <code>turbo_frame_tag</code> как тут:</p><div class="code_container">
<pre><code class="highlight erb"><span class="cp"><%=</span> <span class="n">turbo_frame_tag</span> <span class="n">dom_id</span><span class="p">(</span><span class="n">post</span><span class="p">)</span> <span class="k">do</span> <span class="cp">%></span>
<span class="nt"><div></span>
<span class="cp"><%=</span> <span class="n">link_to</span> <span class="n">post</span><span class="p">.</span><span class="nf">title</span><span class="p">,</span> <span class="n">post_path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="cp"><%</span> <span class="k">end</span> <span class="cp">%></span>
</code></pre>
</div>
<h4 id='turbo-streams' class='inside_page_header'><a href="#turbo-streams">4.3.</a> Turbo Streams</h4><p><a href="https://turbo.hotwired.dev/handbook/streams">Turbo Streams</a> доставляет изменения страницы как фрагменты HTML, обернутые в самовыполняемые элементы <code><turbo-stream></code>. Turbo Streams позволяют транслировать изменения, сделанные другими пользователями, по WebSockets и обновлять части страницы после отправки формы, без запроса загрузки полной страницы.</p><p>Rails предоставляет хелперы HTML и серверной части для упрощения использования Turbo Streams с помощью гема <a href="https://github.com/hotwired/turbo-rails">turbo-rails</a>.</p><p>Используя этот гем, можно добавить Turbo Streams из экшна контроллера:</p><div class="code_container">
<pre><code class="highlight ruby"><span class="k">def</span> <span class="nf">create</span>
<span class="vi">@post</span> <span class="o">=</span> <span class="no">Post</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">post_params</span><span class="p">)</span>
<span class="n">respond_to</span> <span class="k">do</span> <span class="o">|</span><span class="nb">format</span><span class="o">|</span>
<span class="k">if</span> <span class="vi">@post</span><span class="p">.</span><span class="nf">save</span>
<span class="nb">format</span><span class="p">.</span><span class="nf">turbo_stream</span>
<span class="k">else</span>
<span class="nb">format</span><span class="p">.</span><span class="nf">html</span> <span class="p">{</span> <span class="n">render</span> <span class="ss">:new</span><span class="p">,</span> <span class="ss">status: :unprocessable_entity</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>
<p>Rails будет автоматически искать файл вью <code>.turbo_stream.erb</code> и рендерить эту вью после нахождения.</p><p>Отклики Turbo Stream также могут рендериться внутри экшна контроллера:</p><div class="code_container">
<pre><code class="highlight ruby"><span class="k">def</span> <span class="nf">create</span>
<span class="vi">@post</span> <span class="o">=</span> <span class="no">Post</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">post_params</span><span class="p">)</span>
<span class="n">respond_to</span> <span class="k">do</span> <span class="o">|</span><span class="nb">format</span><span class="o">|</span>
<span class="k">if</span> <span class="vi">@post</span><span class="p">.</span><span class="nf">save</span>
<span class="nb">format</span><span class="p">.</span><span class="nf">turbo_stream</span> <span class="p">{</span> <span class="n">render</span> <span class="ss">turbo_stream: </span><span class="n">turbo_stream</span><span class="p">.</span><span class="nf">prepend</span><span class="p">(</span><span class="s1">'posts'</span><span class="p">,</span> <span class="ss">partial: </span><span class="s1">'post'</span><span class="p">)</span> <span class="p">}</span>
<span class="k">else</span>
<span class="nb">format</span><span class="p">.</span><span class="nf">html</span> <span class="p">{</span> <span class="n">render</span> <span class="ss">:new</span><span class="p">,</span> <span class="ss">status: :unprocessable_entity</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>
<p>Наконец, Turbo Streams могут быть инициализированы из модели или фоновой задачи с помощью встроенных хелперов. Эти трансляции могут быть использованы для обновления содержимого с помощью соединения WebSocket всем пользователям, сохраняя содержимое страницы актуальным и оживляя ваше приложение.</p><p>Чтобы транслировать Turbo Stream из модели, комбинируйте колбэк модели, наподобие:</p><div class="code_container">
<pre><code class="highlight ruby"><span class="k">class</span> <span class="nc">Post</span> <span class="o"><</span> <span class="no">ApplicationRecord</span>
<span class="n">after_create_commit</span> <span class="p">{</span> <span class="n">broadcast_append_to</span><span class="p">(</span><span class="s1">'posts'</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre>
</div>
<p>С настроенным соединением WebSocket на странице, вы должны получить обновление наподобие:</p><div class="code_container">
<pre><code class="highlight erb"><span class="cp"><%=</span> <span class="n">turbo_stream_from</span> <span class="s2">"posts"</span> <span class="cp">%></span>
</code></pre>
</div>
<h3 id='zameny-dlya-funktsionala-rails-ujs' class='inside_page_header'><a href="#zameny-dlya-funktsionala-rails-ujs">5.</a> Замены для функционала Rails/UJS</h3><p>Rails 6 поставлялся с инструментом с именем UJS, который позволял разработчикам переопределять метод тэгов <code><a></code>, чтобы выполнять не-GET запросы после нажатия гиперссылки и добавлять диалоги подтверждения до запуска действия. Это было по умолчанию до Rails 7, но теперь рекомендуется использовать Turbo вместо этого.</p><h4 id='metod' class='inside_page_header'><a href="#metod">5.1.</a> Метод</h4><p>Нажатие ссылок всегда приводит к запросу HTTP GET. Если приложение <a href="https://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a>, некоторые ссылки фактически действия, изменяющие данные на сервере, и должны выполняться с помощью не-GET запросов. Этот атрибут позволяет помечать такие ссылки явным методом, таким как "post", "put" или "delete".</p><p>Turbo просканирует теги <code><a></code> в приложении на атрибут данных <code>turbo-method</code> и использует указанный метод при его наличии, переопределив действие GET по умолчанию.</p><p>Например:</p><div class="code_container">
<pre><code class="highlight erb"><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Delete post"</span><span class="p">,</span> <span class="n">post_path</span><span class="p">(</span><span class="n">post</span><span class="p">),</span> <span class="ss">data: </span><span class="p">{</span> <span class="ss">turbo_method: </span><span class="s2">"delete"</span> <span class="p">}</span> <span class="cp">%></span>
</code></pre>
</div>
<p>Это создаст:</p><div class="code_container">
<pre><code class="highlight html"><span class="nt"><a</span> <span class="na">data-turbo-method=</span><span class="s">"delete"</span> <span class="na">href=</span><span class="s">"..."</span><span class="nt">></span>Delete post<span class="nt"></a></span>
</code></pre>
</div>
<p>Альтернативой изменения метода ссылки с помощью <code>data-turbo-method</code> является использование хелпера Rails <code>button_to</code>. По причинам доступности, фактические кнопки и формы предпочтительнее для любых не-GET действий.</p><h4 id='podtverzhdeniya' class='inside_page_header'><a href="#podtverzhdeniya">5.2.</a> Подтверждения</h4><p>Можно спросить дополнительное подтверждение у пользователя, добавив атрибут <code>data-turbo-confirm</code> на ссылки и формы. Пользователю будет представлен диалог JavaScript <code>confirm()</code>, содержащий текст атрибута. Если пользователь выберет отмену, действие не произойдет.</p><p>Добавление этого атрибута на ссылках вызовет диалог при нажатии, а добавление его на формы вызовет его при отправке. Например:</p><div class="code_container">
<pre><code class="highlight erb"><span class="cp"><%=</span> <span class="n">link_to</span> <span class="s2">"Delete post"</span><span class="p">,</span> <span class="n">post_path</span><span class="p">(</span><span class="n">post</span><span class="p">),</span> <span class="ss">data: </span><span class="p">{</span> <span class="ss">turbo_method: </span><span class="s2">"delete"</span><span class="p">,</span> <span class="ss">turbo_confirm: </span><span class="s2">"Are you sure?"</span> <span class="p">}</span> <span class="cp">%></span>
</code></pre>
</div>
<p>Это создаст:</p><div class="code_container">
<pre><code class="highlight html"><span class="nt"><a</span> <span class="na">href=</span><span class="s">"..."</span> <span class="na">data-turbo-confirm=</span><span class="s">"Are you sure?"</span> <span class="na">data-turbo-method=</span><span class="s">"delete"</span><span class="nt">></span>Delete post<span class="nt"></a></span>
</code></pre>
</div>
<p>В случае кнопок, атрибут <code>data-turbo-confirm</code> обязан быть связан со сгенерированной формой, как в этом примере:</p><div class="code_container">
<pre><code class="highlight erb"><span class="cp"><%=</span> <span class="n">button_to</span> <span class="s2">"Delete post"</span><span class="p">,</span> <span class="n">post</span><span class="p">,</span> <span class="ss">method: :delete</span><span class="p">,</span> <span class="ss">form: </span><span class="p">{</span> <span class="ss">data: </span><span class="p">{</span> <span class="ss">turbo_confirm: </span><span class="s2">"Are you sure?"</span> <span class="p">}</span> <span class="p">}</span> <span class="cp">%></span>
</code></pre>
</div>
<div class="banner">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- bottom rusrails -->
<ins class="adsbygoogle"
style="display:inline-block;width:580px;height:400px"
data-ad-client="ca-pub-7764391801669990"
data-ad-slot="7566253867"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12" id="footer">
<p>
<a target="blank" href="https://github.com/rusrails/rusrails"><img src="/assets/github-7cc23602a5ac2465f14c19492358a5a67dc24636761cc723e4d621cea0c09225.png" /></a>
</p>
<p>
<a href="https://creativecommons.org/licenses/by-sa/4.0/">Лицензия CC BY-SA 4.0</a>
"Rails", "Ruby on Rails" и логотип Rails - торговые марки DHH
<!-- Yandex.Metrika counter -->
<script>
(function (d, w, c) {
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter1006929 = new Ya.Metrika({id:1006929,
webvisor:true,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true});
} catch(e) { }
});
var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";
if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }
})(document, window, "yandex_metrika_callbacks");
</script>
<noscript>
<div>
<img style="position:absolute; left:-9999px;" alt="" src="//mc.yandex.ru/watch/1006929" />
</div>
</noscript>
<!-- /Yandex.Metrika counter -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-64955373-1', 'auto');
ga('send', 'pageview');
var trackOutboundLink = function(url) {
ga('send', 'event', 'outbound', 'click', url, {
'transport': 'beacon',
'hitCallback': function(){ }
});
}
</script>
</p>
</div>
</div>
</div>
</div>
<div class="to_top" style="display: block">
<div class="to_top_panel"></div>
</div>
<script src="/assets/application-48ac5c5be8858f5558a99606c2d341f9fee482f22db6deee5def03837c505584.js"></script>
</body>
</html>