Реализация структуры URL / YYYY / MM / Title-Slug с Friendly_Id

Я действительно надеюсь, что кто-то может помочь этому Rails n00b с этой проблемой. В течение последних нескольких дней я исследовал, пробовал, сбоил (и сжигал) способы реализации стандартной структуры URL-адреса / YYYY / MM / Title-Slug для блога, который я собираю. Я обнаружил и успешно реализовал Friendly_Id для обработки слагалификации (вместе с отслеживанием истории), но на всю жизнь я не могу решить часть года / месяца, связанную с проблемой маршрутизации.

Прежде чем я забыл: я использую Rails 4.2.3 и Ruby 2.2.1p85 (потому что, да, я использовал кучу вещей из RailsTutorial.org) :-)

Чтобы свести к минимуму путаницу (или сопутствующий ущерб), я создал очень простое приложение для блогов, чтобы оно работало:

$ rails new blog
[...]
$ cd blog
# (Add friendly_id to Gemfile & install)
$ rails generate friendly_id
$ rails generate scaffold post title content slug:string:uniq
[...]
$ rake db:migrate

Внесены следующие изменения вpost.rb:

class Post < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, use: :slugged

  def year
    created_at.localtime.year
  end

  def month
    created_at.localtime.strftime("%m")
  end

end

posts_controller.rb:

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  def index
    @posts = Post.order('created_at DESC').all
  end

  def show
  end

  def new
    @post = Post.new
  end

  def edit
  end

  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @post.destroy
      respond_to do |format|
        format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
        format.json { head :no_content }
      end
    end

  private

    def set_post
      @post = Post.friendly.find(params[:id])
    end

    def post_params
      params.require(:post).permit(:title, :content, :published_at, :slug)
    end
end

index.html.erb

<p id="notice"><%= notice %></p>

<h1>Listing Posts</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th>Slug</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @posts.each do |post| %>
      <tr>
        <td><%= post.title %></td>
        <td><%= post.content %></td>
        <td><%= post.slug %></td>
        <td><%= link_to 'Show', post_date_path(post) %></td>
        <td><%= link_to 'Edit', edit_post_path(post) %></td>
        <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Post', new_post_path %>

routes.rb:

Rails.application.routes.draw do

  get '/posts', to: 'posts#index', as: :posts_path
  get '/posts/:year', to: 'posts#index', as: :posts_year,
    constraints: { year: /\d{4}/ }
  get '/posts/:year/:month', to: 'posts#index', as: :posts_month,
    constraints: { year: /\d{4}/, month: /\d{1,2}/ }
  get '/posts/:year/:month/:slug', to: 'posts#show', as: :post_date,
    constraints: { year: /\d{4}/, month: /\d{1,2}/, slug: /[a-z0-9\-]+/ }
  resources :posts
end

Эти изменения в основном связаны с обновлением кода Rails3 из этогоStackoverflow Q & A поскольку это сделало меня самым дальним из всех вариантов, которые я обнаружил. Я в настоящее время сталкиваюсь со следующим исключением контроллера:

Showing […]/app/views/posts/index.html.erb where line #24 raised:

No route matches {:action=>"show", :controller=>"posts", :month=>nil, :slug=>nil, :year=>#<Post id: 23, title: "test", content: "", slug: "test-4", created_at: "2015-09-01 21:05:48", updated_at: "2015-09-01 21:05:48">} missing required keys: [:month, :slug, :year]

Другие решения, которые потерпели неудачу другими слегка душераздирающими способами:

«Блог Rails 4 /: год /: месяц /: заголовок с чистой маршрутизацией» (см. Комментарии для ссылки) - похоже, это не работает из-за4.1.2 ошибка, которая, кажется, никогда не была исправлена)«Rails 4.1.2 - to_param избегает слешей (и разрывает приложение)» (см. Комментарии для ссылки) - это может сработать, но я не смог перевести ответ для своих целей«Слизни Friendly_Id с идентификаторами или датами, разделенными косой чертой» (см. Комментарии для ссылки)

Чтобы было ясно: я не предан этому подходу - я более чем счастлив идти совершенно другим путем. Я бы хотел, чтобы мой последний блог функционировал как:

http://www.example.com/blog/ (для индекса)http://www.example.com/2015/ (для индекса 2015 постов)http://www.example.com/2015/09/ (для индекса сообщений с 15 сентября)http://www.example.com/2015/09/pleeze-help-me (за отдельный пост)

Спасибо заранее!

РЕДАКТИРОВАТЬ

В поисках некоторых дополнительных кроличьих ям, чтобы найти решение этой проблемы, мне интересно, будет ли использование перезаписи URL единственным? подход к этому вопросу. У меня интуиция говорит, что он вбивает круглый колышек в квадратную дыру (особенно учитывая, что блог еще не запущен, поэтому нет никаких шансов, что есть дикие ссылки, указывающие на текущую структуру URL), но я не могу найти лучшую альтернативу.

Я нашел два варианта, которые могли бы помочь с подходом перезаписи: рефракция (см. Комментарии для ссылки) и перезапись стойки (см. Комментарии для ссылки)

Есть ли у кого-нибудь мнение об этом альтернативном подходе и / или этих плагинах?

Спасибо!

PS - Похоже, есть обновление для SO-разрешений, которые теперь требуют как минимум 10 репутации, чтобы опубликовать более 2 ссылок, поэтому мне пришлось удалить все ссылки, чтобы опубликовать это редактирование. Я переместил их в комментарии, чтобы сохранить изменения.

Ответы на вопрос(1)

Ваш ответ на вопрос