Implementing / YYYY / MM / Title-Slug URL-Struktur mit Friendly_Id

Ich hoffe wirklich, dass jemand diesem Rails n00b bei diesem Problem helfen kann. Ich habe in den letzten Tagen nachgeforscht, versucht, abgestürzt (-und-gebrannt), wie die Standard-URL-Struktur / YYYY / MM / Title-Slug für ein Blog, das ich zusammenstelle, implementiert werden kann. Ich habe Friendly_Id entdeckt und erfolgreich implementiert, um die Verzögerung (zusammen mit der Verlaufsverfolgung) zu bewältigen, aber für mein ganzes Leben kann ich den Jahr / Monat-Teil des Routing-Problems nicht lösen.

Vor dem Vergessen: Ich verwende Rails 4.2.3 und Ruby 2.2.1p85 (weil ich ja ein paar Dinge von RailsTutorial.org genutzt habe): -)

Um Verwirrung (oder Kollateralschäden) zu minimieren, habe ich eine supereinfache Blog-App erstellt, um zu versuchen, alles zum Laufen zu bringen:

$ 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

Nimmt die folgenden Änderungen an @ v 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

Diese Änderungen beziehen sich hauptsächlich auf die Aktualisierung des Rails3-Codes von diesemStackoverflow Q & A wie das hat mich am weitesten aus anderen Optionen, die ich entdeckt habe. Ich stoße derzeit auf die folgende Controller-Ausnahme:

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]

Weitere Lösungen, die auf andere Art und Weise versagt haben:

"Rails 4-Blog /: Jahr /: Monat /: Titel mit sauberem Routing" (siehe Kommentare für den Link) - dies scheint aufgrund eines @ nicht zu funktionier 4.1.2 Fehler, der scheinbar nie behoben wurde) "Rails 4.1.2 - to_param entfernt Schrägstriche (und bricht die App ab)" (siehe Kommentare für den Link) - das mag funktionieren, aber ich konnte die Antwort nicht für meine Zwecke übersetzen "Friendly_Id-Slugs mit durch Schrägstriche getrennten IDs oder Datumsangaben" (Link siehe Kommentare)

Um klar zu sein: Ich bin nicht an diesen Ansatz gebunden - ich bin mehr als glücklich, einen ganz anderen Weg zu gehen. Ich möchte nur, dass mein letzter Blog wie folgt funktioniert:

http://www.example.com/blog/ (für den Index)http://www.example.com/2015/ (für einen Index von 2015 Beiträgen)http://www.example.com/2015/09/ (für einen Index der Beiträge vom 15. September)http://www.example.com/2015/09/pleeze-help-me (für einen einzelnen Beitrag)

Vielen Dank im Voraus

BEARBEITE

In einige zusätzliche Kaninchenlöcher gehen, um eine Lösung für dieses Problem zu finden, frage ich mich, ob die Verwendung von URL-Umschreiben die einzige wäre? Ansatz für dieses Problem. Meiner Meinung nach schlägt es einen runden Stift in ein viereckiges Loch (zumal das Blog noch nicht online ist, es also keine Möglichkeit gibt, dass wilde Links auf die aktuelle URL-Struktur verweisen), aber ich scheitere um eine bessere Alternative zu finden.

Ich habe zwei Optionen gefunden, die beim Umschreiben helfen könnten: Brechung (siehe Kommentare für den Link) und Rack-Umschreiben (siehe Kommentare für den Link).

Hat jemand eine Eingabe zu diesem alternativen Ansatz und / oder diesen Plugins?

Vielen Dank

PS - Es scheint ein Update der SO-Berechtigungen zu geben, für das jetzt mindestens 10 Reputation erforderlich sind, um mehr als 2 Links zu veröffentlichen. Ich musste daher alle Links entfernen, um diese Änderung zu veröffentlichen. Ich habe sie in die Kommentare verschoben, damit ich die Bearbeitung speichern kann.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage