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.