Stimulus — это легковесный JavaScript-фреймворк, ориентированный на поведение элементов страницы. В связке с Ruby on Rails он позволяет создавать интерактивные интерфейсы без сложной клиентской архитектуры. Rails предоставляет встроенные возможности для подключения Stimulus через Hotwire и Webpacker/Importmaps, что делает интеграцию максимально удобной.
Rails 7 по умолчанию использует Importmap, позволяющий подключать JavaScript-библиотеки без сборщиков типа Webpack.
bin/importmap pin stimulus
bin/rails generate stimulus имя_контроллера
Эта команда создаст структуру файлов:
app/javascript/controllers/имя_контроллера_controller.js
application.js:import { Application } from "@hotwired/stimulus"
import { definitionsFromContext } from "@hotwired/stimulus-loading"
const application = Application.start()
const context = require.context("controllers", true, /\.js$/)
application.load(definitionsFromContext(context))
Контроллер Stimulus состоит из нескольких основных частей:
Пример контроллера кнопки «Like»:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["button", "count"]
static values = { count: Number }
connect() {
console.log(`Начальное значение лайков: ${this.countValue}`)
}
increment() {
this.countValue++
this.countTarget.textContent = this.countValue
}
}
HTML-разметка для данного контроллера:
<div data-controller="like" data-like-count-value="0">
<button data-action="click->like#increment" data-like-target="button">Like</button>
<span data-like-target="count">0</span>
</div>
Stimulus отлично работает с AJAX-формами Rails через Turbo. Пример обновления списка комментариев без перезагрузки страницы:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["comments", "form"]
submit(event) {
event.preventDefault()
const formData = new FormData(this.formTarget)
fetch(this.formTarget.action, {
method: "POST",
body: formData,
headers: { "Accept": "text/vnd.turbo-stream.html" }
})
}
}
<div data-controller="comments">
<div data-comments-target="comments">
<%= render @comments %>
</div>
<%= form_with model: Comment.new, data: { action: "submit->comments#submit" } do |f| %>
<%= f.text_area :body %>
<%= f.submit "Add Comment" %>
<% end %>
</div>
comments-target,
обеспечивая мгновенное отображение новых комментариев.Turbo Frames позволяют изолировать части страницы для обновления, что отлично сочетается с контроллерами Stimulus.
Пример:
<turbo-frame id="cart">
<div data-controller="cart" data-cart-items-value="<%= @cart.items.count %>">
<%= render @cart.items %>
</div>
</turbo-frame>
Контроллер может управлять состоянием корзины без вмешательства в остальную страницу:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = { items: Number }
connect() {
this.updateBadge()
}
addItem() {
this.itemsValue++
this.updateBadge()
}
updateBadge() {
document.querySelector("#cart-badge").textContent = this.itemsValue
}
}
В больших Rails-приложениях рекомендуется:
Использовать namespaced controllers, чтобы избежать конфликтов.
app/javascript/controllers/admin/users_controller.jsРазделять контроллеры по функциональным зонам страницы.
Применять targets и values для минимизации
поиска DOM элементов через querySelector.
Использовать actions вместо прямой привязки обработчиков через JavaScript.
connect() автоматически вызывается при
инициализации.turbo:load или обновлять контроллеры через
application.load() повторно.Stimulus в связке с Ruby on Rails обеспечивает простую, но мощную архитектуру для интерактивного фронтенда, оставляя серверу роль обработки данных и логики, а клиенту — управление поведением элементов страницы. Контроллеры легко масштабируются, интегрируются с Turbo, формами и другими Rails-инструментами, что делает их идеальным выбором для современных Rails-приложений.