Простая инструкция для внедрения ЧПУ или любого рода слагов в проект на Ruby on Rails.
В примере будут использованы гемы FriendlyID и Babosa (для поддержки кириллицы).
Базовая настройка:
1. Создание нового проекта
1 |
rails new article_friendly_id |
2. Установка необходимых гемов
Добавьте в Gemfile две строки:
1 2 |
gem 'friendly_id', '~> 5.1.0' gem 'babosa' |
3. Создание модели “Статья”
1 2 |
rails g scaffold Post title:string category:string rails g migration add_slug_to_post slug:string |
4. Настройка FriendlyID для модели “Статья”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
require 'babosa' class Post < ApplicationRecord include FriendlyId friendly_id :slug_candidates, :use => [:slugged] def slug_candidates [ :title, [:title, :category] ] end def normalize_friendly_id(text) text.to_slug.normalize! :transliterations => [:russian, :latin] end end |
Дополнительно необходимо внести изменения в контроллер:
1 2 3 |
def set_post @post = Post.friendly.find(params[:id]) end |
5. Всё
Хранение истории слагов
При базовой настройке слаг создаётся один раз и навсегда. Если необходимо чтобы слаг создавался каждый раз при изменении атрибута из которого создаётся слаг, то необходимо в модель добавить следующий метод:
1 2 3 |
def should_generate_new_friendly_id? title_changed? || super end |
Но, если вы использовали слаг в качестве адреса страницы, то при изменении слага, все предыдущие слаги закэшированные в поисковых системах будут вести на 404. Чем FriendlyID из коробки поддерживает хранение истории для слагов.
1. Установка модуля истории из гема
1 2 |
rails g friendly_id rake db:migrate |
2. Изменение модели для поддержки историчности слагов
1 |
friendly_id :slug_candidates, :use => [:slugged, :history] |
3. Пересохранение всех статей с созданием слагов в истории
Если у вас уже есть какое-то количество сохранных статей, то при их пересохранении создадутся новые слаги, с поддержкой истории. Но, все существующие всё таки будут вести на 404. Чтобы это предотвратить надо пересохранить существующие статьи с текущими слагами.
1 2 3 |
def should_generate_new_friendly_id? true end |
1 |
Post.find_each(&:save) |
If you are able to, it helps even more if you can fork FriendlyId on Github, and add a test that reproduces the error you are experiencing.