8
8

More than 5 years have passed since last update.

Rails(Grape)でAPIを作成する備忘録4(タグ情報の付与と絞込みの実装)

Last updated at Posted at 2015-03-19

今更ですが

今までフロントエンドのみ触ってきたサーバーサイドに全く触れたことのない学生が、勉強しながら書いてます。
全部完成させてこの記事を書いているわけでは無いので見通しの良い、使えるコードであるかはわかりません。ご了承ください。

僕みたいなサーバーサイド触ったこと無いけどAPI作ってみるかって人の参考に少しでもなればと思います。

ドキュメントへのタグ情報の付与

grape-entityのインストール

Gemfile
  gem 'grape-entity'

その後bundle install

Entityを定義
これを使えば簡単に埋め込みができたり無駄なものを返さなくて良くなります

lib/api/entity.rb
module Entities
  class Tag < Grape::Entity
    expose :id, :name
  end

  class Document < Grape::Entity
    expose :id, :content, :title, :user_id, :created_at
    expose :tags, using: Entities::Tag
  end
end

includeさせる

lib/api/document_api.rb
  desc "returns all documents"
  get do
    document = Document.includes(:tags)
    present document, with: Entities::Document
  end

これでhttp://localhost:3000/api/document
にアクセスすると

{
  id: 1,
  content: "ほげふがぴよ",
  title: "ほげほげ",
  user_id: 1,
  created_at: "2015-03-17T04:08:38.185Z",
  tags: [
          {
            id: 1,
            name: "ふがふが"
          }
        ]
}

タグ情報が含まれて帰ってきます

絞込みの実装

タグによるドキュメントの絞り込みを実装しました。
URLの指定の仕方がこれでいいのか悩みましたがとりあえずこういう形にしておきます。

lib/api/tag_api.rb
class Tag_API < Grape::API
  resource "tags" do
    params do
      requires :tag_id, type: Integer
    end
    # http://localhost:3000/api/tags/{:tag_id}/document
    get ':tag_id/documents' do
      document = Document.includes(:tags).where(tags: {id: params[:tag_id]})
      present document, with: Entities::Document
      # 以下だとSQLがドキュメント毎に走るN+1問題
      # tag = Tag.find(params[:tag_id])
      # present tag.documents, with: Entities::Document
    end
  end
end

コメントアウトしているようなコードで、検索してからドキュメントを返そうとするとドキュメント毎にSQLが走ってしまいます
研究室のWiki程度ならこれくらいでもいいかもしれないですが、それなりにアクセスされる何かを作る場合はお気をつけください

8
8
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
8
8