Implementando / AAAA / MM / Estructura URL de Título-Slug con Friendly_Id

Realmente espero que alguien pueda ayudar a este Rails n00b con este problema. En los últimos días, he estado investigando, probando, bloqueando (y quemando) cómo implementar la estructura de URL estándar / AAAA / MM / Title-Slug para un blog que estoy armando. He descubierto e implementado con éxito Friendly_Id para manejar la sluggification (junto con el seguimiento del historial), pero por mi vida no puedo resolver la parte Año / Mes del problema de enrutamiento.

Antes de que me olvide: estoy usando Rails 4.2.3 y Ruby 2.2.1p85 (porque sí, aproveché un montón de cosas de RailsTutorial.org) :-)

Para minimizar la confusión (o el daño colateral), he diseñado una aplicación de blog súper simple para intentar que todo funcione:

$ 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

Hizo los siguientes cambios apost.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

Estos cambios se deben principalmente a la actualización del código Rails3 a partir de esteStackoverflow Q&A ya que eso me ha llevado más lejos de otras opciones que he descubierto. Actualmente me encuentro con la siguiente excepción de controlador:

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]

Otras soluciones que han fallado en otras formas un poco desgarradoras:

"Blog de Rails 4 /: año /: mes /: título con enrutamiento limpio" (ver comentarios para el enlace) - esto parece no funcionar debido a un4.1.2 error que parece no haberse solucionado nunca)"Rails 4.1.2 - to_param escapa slashes (y rompe la aplicación)" (ver comentarios para el enlace) - esto puede funcionar, pero no pude traducir la respuesta para mis propósitos"Slugs Friendly_Id con identificadores o fechas separadas por barras" (ver comentarios para el enlace)

Para ser claros: no estoy casado con este enfoque, estoy más que feliz de ir por un camino completamente diferente. Solo me gustaría que mi blog final funcione como:

http://www.example.com/blog/ (para el índice)http://www.example.com/2015/ (para un índice de publicaciones de 2015)http://www.example.com/2015/09/ (para un índice de publicaciones del 15 de septiembre)http://www.example.com/2015/09/pleeze-help-me (para una publicación individual)

¡Muchas gracias de antemano!

EDITAR

Al analizar algunos agujeros de conejo adicionales para obtener una solución a esto, me pregunto si usar la reescritura de URL sería la única. enfoque para este tema. Mi instinto dice que está golpeando una clavija redonda en un agujero cuadrado (especialmente dado que el blog aún no está activo, por lo que no hay posibilidad de que haya enlaces en la naturaleza que apuntan a la estructura de URL actual), pero estoy fallando para encontrar una mejor alternativa

He encontrado dos opciones que podrían ayudar con el enfoque de reescritura: refracción (ver comentarios para el enlace) y reescritura en rack (ver comentarios para el enlace)

¿Alguien tiene alguna entrada sobre este enfoque alternativo y / o estos complementos?

¡Gracias!

PD: parece haber una actualización de los permisos SO que ahora requieren al menos 10 reputación para publicar más de 2 enlaces, por lo que tuve que eliminar todos los enlaces para publicar esta edición. Los moví a los comentarios para poder guardar la edición.

Respuestas a la pregunta(1)

Su respuesta a la pregunta