Здесь я опишу, как я боролся с перемещением страниц на новые URL-адреса.
Эта статья предназначена для новичков в Ruby On Rails. Изначально у меня есть свой проект на Ruby on Rails, структура url в нем выглядит так: /locale/group/product пример: /ru/bar-code-scanners/datalogic-magelan-1100i группа И продукт это постоянная ссылка — строка, используемая для поиска в БД по идентификатору местоположения.
Проблема в том, что пользователи, добавляющие контент на сайт, иногда допускают ошибки в постоянной ссылке.
Вот пример: /ru/bar-code-scanners/datalogic-magelan-1100i Ошибка в том, что Магелан пишется с двумя ll - маг я буду ан.
Но товар добавлен относительно давно и страница уже проиндексирована поисковыми системами, поэтому задача — исправить постоянную ссылку и настроить перенаправление на новый URL. Конечно, эту проблему можно решить на уровне nginx или apache. Но обычно доступ к веб-серверу имеют только администраторы, да и плюс редактирование редиректа для нескольких локалей — тоже довольно рутинная задача.
Поэтому я решил автоматизировать это дело, для этого создал простую модель Redirection с полиморфной связью, то есть она может принадлежать как Product, так и Group. Файл миграции 20131113223332_create_redirections.rb
А вот как выглядит сама модель Redirection:class CreateRedirections < ActiveRecord::Migration def change create_table :redirections do |t| t.references :redirectable, polymorphic: true t.string :permalink t.timestamps end end end
class Redirection < ActiveRecord::Base
attr_accessible :permalink
belongs_to :redirectable, polymorphic: true
def self.product(permalink)
redirection = Redirection.where(permalink: permalink, redirectable_type: "Product").
first
redirection.redirectable if not redirection.nil?
end
def self.group(permalink)
redirection = Redirection.where(permalink: permalink, redirectable_type: "Group").
first
redirection.redirectable if not redirection.nil?
end
end
Теперь осталось только подкорректировать каждую модель, для которой необходимо настроить перенаправление Group и Product. Добавьте соединение в модель перенаправления.
has_many :redirections, as: :redirectable, :dependent=>:destroy
Теперь нам необходимо реализовать отслеживание изменений атрибута постоянной ссылки и при необходимости создать запись Redirection.
К счастью, все модели, на которые у меня есть постоянная ссылка, унаследованы от одного из моих промежуточных классов, AbstractContent. Так что достаточно добавить код отслеживания изменений постоянных ссылок только в этот класс, не нарушая при этом принципов DRY.
И именно за это я люблю Rails — само отслеживание оказалось простым в реализации.
Rails расширяет нашу модель и ее атрибуты с помощью очень удобного _changed? методы.
и был.
Все, что вам нужно сделать, это добавить обратный вызов after_save, который будет отслеживать изменения и, при необходимости, создавать новую запись модели перенаправления.
class AbstractContent < ActiveRecord::Base
self.abstract_class = true
after_save :check_permalink_changes
def check_permalink_changes
if self.permalink_changed?
if self.permalink_was
self.redirections.create!(permalink: self.permalink_was)
end
end
end
end
Остаётся только настроить само перенаправление в контроллере class GroupsController < ApplicationController
def show
@group = Group.find_by_permalink(params[:id])
if @group.nil?
@group = Redirection.group(params[:id]) || not_found
redirect_to group_path(@group), status: 301
end
end
end
И не забудьте добавить статус 301 - переехал навсегда.
По умолчанию — 302 — перемещено временно.
Думаю, что приводить здесь код второго контроллера нет смысла, поскольку он аналогичен.
Еще отмечу, что в реальном коде проекта поиск find_by_permalink осуществляется через кеш; find_in_cache был удален отсюда для упрощения примера.
Чтобы было удобно вызывать ошибку 404, я добавил в ApplicationController метод not_found, который вызывает Exception. def not_found
raise ActionController::RoutingError.new('Not Found')
end
Кстати, если вы не хотите рыться в Production.log, а хотите просмотреть все ошибки, запросив URL именно той структуры, которая нам нужна /group/product. Здесь удобно добавить логирование всех вызовов not_found в отдельный файл.
P.S. Ну, вы также можете дополнительно добавить RedirectionsController для управления и отслеживания всех перенаправлений.
Теги: #ruby onrails #redirect #ruby #ruby onrails
-
Нет Вариантов
19 Oct, 24 -
Diy-Фандрайзинг И Краудфандинг
19 Oct, 24 -
Увеличьте Свой Сайт. Оглавление
19 Oct, 24 -
Дизайн - Это...
19 Oct, 24