【Rails】自作ブログにパーマリンク(任意のURL)を設定できるようにしました

自作ブログにパーマリンク(任意のURL)を設定できるようにしたので、そのメモ書きです。

以前は、記事を投稿するとURLがhttps://yamatabi.jp/posts/11のように、投稿した記事のIDがそのままURLになってしまっていました。

それでもいいんですが、URLがIDだと検索エンジン側から見たら「その記事がどんな記事か」がわからない(SEO的にも良くない?)ですし、何より僕が気になってしょうがないw

やはり、記事ごとに固有のURLを設定できた方が見栄えがいいじゃないですかw

ということで、今回はhttps://yamatabi.jp/posts/11のようなURLからhttps://yamatabi.jp/hokkaido-trip-day-1のような独自のURLを設定できるようにしました。

あわせて読みたい
【Rails】URL の id を任意のカラム名(アカウント名など)に変更する ユーザープロフィールなどを表示するときに、URLにはユーザーを識別するためのidが表示されます。 このidを、以下のようにアカウント名(ユーザー名)に変更して表示す...
目次

パーマリンクを設定できるようにするまでの流れ

パーマリンク保存用のカラム作成

パーマリンクを保存するためのカラムpermalinkを追加します。

$ rails g migration add_permalink_to_posts permalink:string

作成されたマイグレーションファイルを確認。

class AddPermalinkToPosts < ActiveRecord::Migration[7.0]
  def change
    add_column :posts, :permalink, :string
  end
end

マイグレーションを実行してカラムを追加します。

$ rails db:migrate

ルーティングの設定

パーマリンク設定前は以下のようなルーティング設定にしていました。(draftは下書き保存用のルーティング設定)

  resources :posts do
    collection do
      get "draft"
    end
  end

各アクションのルーティングはこちら↓

    draft_posts GET    /posts/draft(.:format)     posts#draft
          posts GET    /posts(.:format)           posts#index
                POST   /posts(.:format)           posts#create
       new_post GET    /posts/new(.:format)       posts#new
      edit_post GET    /posts/:id/edit(.:format)  posts#edit
           post GET    /posts/:id(.:format)       posts#show
                PATCH  /posts/:id(.:format)       posts#update
                PUT    /posts/:id(.:format)       posts#update
                DELETE /posts/:id(.:format)       posts#destroy

これを、以下のように書き換えます↓

  resources :posts, only: [:index, :new] do
    collection do
      get "draft"
    end
  end
  get ":permalink", to: "posts#show", as: "post"
  post ":permalink", to: "posts#create"
  get ":permalink/edit", to: "posts#edit", as: "edit_post"
  patch ":permalink", to: "posts#update"
  put ":permalink", to: "posts#update"
  delete ":permalink", to: "posts#destroy"

書き換えた後のルーティングです↓

    draft_posts GET    /posts/draft(.:format)     posts#draft
          posts GET    /posts(.:format)           posts#index
       new_post GET    /posts/new(.:format)       posts#new
           post GET    /:permalink(.:format)      posts#show
                POST   /:permalink(.:format)      posts#create
      edit_post GET    /:permalink/edit(.:format) posts#edit
                PATCH  /:permalink(.:format)      posts#update
                PUT    /:permalink(.:format)      posts#update
                DELETE /:permalink(.:format)      posts#destroy

indexおよびnewアクションについてはパーマリンクを設定する必要がないのでそのままにしています。

ただ、このままだとパーマリンクの設定をしてもパーマリンクのURLにアクセスできないため、モデルファイルに次のような設定をします。

URLにパーマリンクを表示させるためのメソッドを追加(post.rb)

モデルファイルpost.rbに以下を追記します。

class Post < ApplicationRecord
  ...
 
  def to_param
    permalink
  end

end

これで、設定したパーマリンクにアクセスできるようになります。

パーマリンク入力フォームの追加

パーマリンク用の入力フォームを追加します↓

<%= form_with(model: post) do |form| %>

   ......

  <!-- パーマリンク -->
  <div class="my-3">
    <%= form.label :permalink, for: "postPermalinkInput", class: "form-label fw-bold" %>
    <%= form.text_field :permalink, class: "form-control", id: "postPermalinkInput" %>
  </div>

  ......

<% end %>

これでパーマリンクを入力、保存できるようになりました。

パーマリンクを保存後、投稿した記事にアクセスすると設定したパーマリンクがURLに表示されているはずです。

ただ、現時点ではパーマリンクの文字種類に制限がなかったり、同一のパーマリンクを入力できてしまうため、この辺のバリデーションも実装する必要があります。

(Postモデルでバリデーションかけてもいいのですが、僕はリアルタイムでバリデーションチェックがしたかったのでJavaScriptで実装しました)

バリデーションについてはまた別記事で紹介します。

パーマリンクが未入力の場合の対処(適当なパーマリンクを自動生成)

先ほどのフォームで、パーマリンクを未入力にしたまま保存してしまうことを想定し、パーマリンクが未入力でも適当なパーマリンクを自動生成、割り当てするようにします。

post.rbに以下の内容を追記します↓

class Post < ApplicationRecord
  ...

  before_create :set_post_permalink # ←追記
 
  def to_param
    permalink
  end

 # ↓追記
 private
    # 初期のパーマリンクを生成する(パーマリンクを指定しなかった場合)
    def set_post_permalink
      while self.permalink.blank? || Post.find_by(permalink: self.permalink).present? do
        self.permalink = "post-#{rand(99999999)}"
      end
    end

end

パーマリンクの文字列はなんでもいいですが、他の投稿と被らないようにするためにパーマリンクの文字列をランダムにし、かつwhile文でデータベース上に同一のパーマリンクが存在しないかチェックしています(生成したパーマリンクと同一のものがなければそのまま保存する)。

以上です。

開発環境

  • Ruby 3.1.2
  • Ruby on Rails 7.0.4.3
  • Bootstrap 5.2.3
  • M1 Macbook Air 2020
  • mac OS Monterey (ver. 12.4)

自作ブログのソースコード

GitHub
GitHub - hirokirokki0820/yamatabi-blog Contribute to hirokirokki0820/yamatabi-blog development by creating an account on GitHub.
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

愛知の34歳。無職で暇になり始めたプログラミング(Ruby on Rails)の忘備録をまとめたブログです。最近は別にやりたいことができたのでプログラミングほぼやっていません。気が向いたらまた再開するかも。僕の日常はメインブログの方で更新しています。

コメント

コメントする

目次