2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Ruby on RailsでURLにスラッグを使用する

Posted at

はじめに

学習用のメモとして投稿します。
先日RealWorld という OSS のプロジェクトで、APIのエンドポイントを実装する機会がありました。
そのAPIスペックに、スラッグの使用が含まれていたので、どのように実装したかについて書いていきます。

APIスペック

RealWorldでは、ブログ投稿プラットフォームを作っていきます。
多くのエンドポイントがありますが、今回はスラッグに関する部分のみに絞ります。

①記事の作成

  • リクエスト
    GET /api/articles/:slug

  • レスポンス

{
  "article": {
    "slug": "how-to-train-your-dragon",
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "It takes a Jacobian",
    "tagList": ["dragons", "training"],
    "createdAt": "2016-02-18T03:22:56.637Z",
    "updatedAt": "2016-02-18T03:48:35.824Z",
    "favorited": false,
    "favoritesCount": 0,
    "author": {
      "username": "jake",
      "bio": "I work at statefarm",
      "image": "https://i.stack.imgur.com/xHWG8.jpg",
      "following": false
    }
  }
}

②記事の投稿

  • リクエスト
    POST /api/articles
// リクエストボディ例
{
  "article": {
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "You have to believe",
    "tagList": ["reactjs", "angularjs", "dragons"]
  }
}
  • レスポンス
{
  "article": {
    "slug": "how-to-train-your-dragon",
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "You have to believe",
    "tagList": ["reactjs", "angularjs", "dragons"],
    "createdAt": "2016-02-18T03:22:56.637Z",
    "updatedAt": "2016-02-18T03:48:35.824Z",
    "favorited": false,
    "favoritesCount": 0,
    "author": {
      "username": "jake",
      "bio": "I work at statefarm",
      "image": "https://i.stack.imgur.com/xHWG8.jpg",
      "following": false
    }
  }
}

実装: マイグレーション

GET /api/articles/:slugでスラッグは記事特定に使用されているため、データベースに保存する必要があります。
また、レスポンスの内容を見ると、スラッグはタイトルをベースにした内容になっています。
そうすると、①スラッグはuniqueである必要があり、②スラッグのベースとなるタイトルもuniqueである必要があります。

class CreateArticles < ActiveRecord::Migration[7.0]
  def change
    create_table :articles do |t|
      t.string :slug, null: false, unique: true
      t.string :title, null: false, unique: true
# ... 略

実装: モデル

POST /api/articlesでリクエストボディにスラッグは含まれないため、こちらで作成する必要があります。そこで、タイトルからスラッグを作成するメソッドを作成し、データベースに保存する前に呼び出すようにします。スラッグの作成には色々な方法が考えられますが、今回のAPIスペックを満たすためには、rails6で追加されたparameterizeメソッドで実装できそうだったので、これを使用しました。

また、URLでidではなく、スラッグを使用するために、to_paramメソッドをオーバーライドします。

class Article < ApplicationRecord
  before_save :generate_slug
  validates :title, presence: true, uniqueness: true

  def generate_slug
    self.slug = self.title.parameterize if title.present?
  end

  def to_param
    slug
  end
# ... 略

実装: コントローラー

記事の作成に成功すれば、データベースには、uniqueなスラッグが書き込まれているはずです。
これでスラッグを条件にしてデータが取得できるようになります。

@article = Article.find_by(slug: params[:slug])

参考にした記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?