Rails + Nuxt ~モデルの作成から表示(index)まで~

Rails + Nuxt ~モデルの作成から表示(index)まで~

前回の記事でAPIの通信はできたのでここからは実際にモデルを作成していきます。

前回の記事はこちら: https://tns-blog.com/1

今回作成するアプリのER図はこのようになっています。

Twitterみたいな簡易SNSです。

ユーザーは複数の投稿ができさらに投稿に対していいねができる。

大まかな流れとしては下記のようになります。

  1. PostモデルのCRUD
    1. Postモデルの作成(user_idはなし)
    2. 一覧表示(index)
    3. 新規登録(create)
    4. 詳細表示(show)
    5. 更新(update)
    6. 削除(delete)
  2. PostモデルとUserモデルの紐付け
    1. ユーザー認証(firebase使用)
    2. Userモデル作成
    3. PostモデルとUserモデルアソシエーションを組む
    4. (番外編) Google, facebook, twitter, メール認証
  3. Likeモデル作成

これから数回の記事に渡って1. PostモデルのCRUDを実装していきます。

1.Postモデルの作成

まずデータを保存するためにPostモデルを作成します。

api $ rails g model post

Postモデルが作成できたらマイグレーションファイルを編集していきます。

今回はcontentモデルはcontentカラムの値を空で保存したくないのでNULL制約を設定します。

api/db/migrate/xxxxx_create_posts.rb

class CreatePosts < ActiveRecord::Migration[6.1]
  def change
    create_table :posts do |t|
      t.string :content, null: false

      t.timestamps
    end
  end
end

上記のようにカラムにNULL制約を設定できたらその設定を反映させます。

api $ rails db:migrate
== 20210119222112 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0210s
== 20210119222112 CreatePosts: migrated (0.0211s) =============================

postsテーブルが作成されました。

次にコンソールでレコードを作成していきます。

2. レコード作成(Rails)

まだアプリの方でPostモデルを保存できないのでひとまずターミナルの方で3つレコードを作成します。

api $ rails c
> Post.create!(content: 'rails content 1')
> Post.create!(content: 'rails content 2')
> Post.create!(content: 'rails content 3')

これでPostモデルのレコードが3つ作成できました。

次はルーティングを定義してコントローラーを作成してindexアクションを定義しましょう。

3.ルーティング生成(Rails)

実際にnuxt側からAPIを叩く際のルーティングを生成します。

api/config/routes.rb

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :hello, only: [:index] # 不要なので削除しても大丈夫です
      resources :posts, only: [:index]
    end
  end
end

このように記述できたらターミナルでルーティングを確認します。

api $ rails routes | grep posts
api_v1_posts  GET  /api/v1/posts(.:format)  api/v1/posts#index

ルーティングが作成できました。これでNuxt側は http://localhost:3000/api/v1/posts のGETリクエストを叩けばOKです。

次にAPIを叩いた時に返すレスポンスを作成していきます。

4.コントローラ作成(Rails)

次にコントローラを作成していきます。

まず、api/app/controllers/api/viの中に下に posts_controller.rb を作成してください。

ファイルが作成できたら以下のように記述していきます。

api/app/controllers/api/v1/posts_controller.rb

module Api
  module V1
    class PostsController < ApplicationController
      def index
        @posts = Post.all
      end
    end
  end
end

ここまでは普段のrailsのアプリケーションと同じですね。

ここからnuxtにデータを渡すときはjsonで渡す必要があるのでいつもとは違う記述になります。

5.ビュー作成, jbuilder導入(Rails)

まずjbuilderというgemをインストールします。

jbuilderの書き方は下記の記事に詳しくのっているのでこちらを参照してください。

Railsのjbuilderの書き方と便利なイディオムやメソッド : https://qiita.com/ryouzi/items/06cb0d4aa7b6527b3645

Gemfileのjbuilderのコメントアウトを外してbundle installします。

api/app/Gemfile

gem 'jbuilder', '~> 2.7' # コメントアウトを外す
api $ bundle install

次にviewsの中にindex.jbuilderファイルを作成します。

中身は下記のようになります。

api/app/views/api/v1/posts/index.jbuilder

json.posts @posts do |post|
  json.extract! post, :id, :content, :created_at
end

簡単に説明すると@postsの一つ一つのレコードのid, content, created_atのカラムを取得してjsonで返します。

ここまで記述できたらhttp://localhost:3000/api/v1/posts へアクセスします。

http://localhost:3000/api/v1/posts へアクセスすると下記のようなjsonが返ってきました。

{"posts":[{"id":1,"content":"rails content1","created_at":"2021-01-20T22:56:54.543Z"},{"id":2,"content":"rails content 2","created_at":"2021-01-19T22:33:18.584Z"},{"id":3,"content":"rails content 3","created_at":"2021-01-19T22:33:16.503Z"}]}

これでRails側の準備は整いました。

続いてNuxt側で http://localhost:8080/posts にアクセスしたらPostモデルの一覧を表示できるように実装していきます。

6. postsページの作成(Nuxt)

まずpagesディレクトリにpostsというディレクトリを作成してその中にindex.vueというファイルを作成します。

そうするとnuxt側で自動で http://localhost:8080/posts のルーティングを生成してくれます。

ルーティングは.nuxt/router.jsに記述されています。

front/.nuxt/router.js

...省略

export const routerOptions = {
  mode: 'history',
  base: '/',
  linkActiveClass: 'nuxt-link-active',
  linkExactActiveClass: 'nuxt-link-exact-active',
  scrollBehavior,

  routes: [{
    path: "/posts",  -------- 追加される
    component: _2e8d5e7c,
    name: "posts"
  }, {
    path: "/",
    component: _2c66c790,
    name: "index"
  }],

  fallback: false
}

ファイルを作成したら下記のように記述します。

front/pages/posts/index.vue

<template>
  <div>
    この中にHTMLを記述する
  </div>
</template>

<script>
export default {
  // ここにデータの定義やデータ処理のfunctionなどを記述する
}
</script>

<style>
  /* スタイル情報を記述する */
</style>

Vueのファイルには大きく分けてtemplateタグ、scriptタグ、styleタグの3つのタグで構成されます。

templateタグ内にはHTML情報を記述して、scriptタグにはデータの定義やデータの処理を記述、styleタグ内はスタイル情報を記述します。

ファイルの記述が完了したら http://localhost:8080/posts にアクセスします。

アクセスすると下記画像のように表示されます。

次はpostsにアクセスした時にRails側とaxios通信してPostモデルのデータを取得して表示します。

7. axios通信(Nuxt)

先ほどのファイルを下記のように書き換えます。

front/pages/posts/index.vue

<template>
  <div class="container py-5">
    <b-card
      v-for="post in posts"
      :key="post.id"
    >
      <b-card-text>
        {{ post.content }}
      </b-card-text>
    </b-card>
  </div>
</template>

<script>
export default {
  data: () => {
    return {
      posts: [],
    }
  },

  mounted() {
    this.fetchContents()
  },

  methods: {
    fetchContents() {
      const url = "/api/v1/posts"
      this.$axios.get(url)
        .then((res) => {
          // リクエスト成功時の処理
          console.log(res)
        })
        .catch(() => {
          // リクエスト失敗時の処理
        })
    },
  }
}
</script>
mounted() {
  this.fetchContents()
},

ページがマウントされたタイミングでfetchContents()を実行します。

methods: {
  fetchContents() {
    const url = "/api/v1/posts"
    this.$axios.get(url)
        .then((res) => {
          // リクエスト成功時の処理
          console.log(res)
        })
        .catch(() => {
          // リクエスト失敗時の処理
        })
  },
}

fetchContents のファンクションが実行されたら http://localhost:3000/api/v1/posts のGETリクエストを送ります。

thenの中にはリクエストに成功したときの処理を記述します。

catchの中にはリクエストに失敗したときの処理を記述します。

もう一度 http://localhost:8080/posts にアクセスしてChromeの開発者ツールを開きConsoleを確認します。

アクセスすると上記のようにレスポンスが返ってきます。res.data.postsにRailsで作成したPostモデルのレコードが入っていることがわかります。なのでこれをVueのdata()で定義したpostsに入れます。

8. データ描画(Nuxt)

では記述を修正します。

methods: {
  fetchContents() {
    const url = "/api/v1/posts"
    this.$axios.get(url)
      .then((res) => {
        this.posts = res.data.posts
      })
  },
}

このように修正したらもう一度ページをリロードします。

下記のようにrails側で作成したpostsの一覧が表示されたら成功です。

Postモデルの一覧表示が実装できました。

次の記事ではPostモデルの新規作成~詳細表示までを実装します。

次の記事はこちら: Rails + Nuxt モダンなアプリケーションの作成~モデルの作成から表示まで~

プログラミングカテゴリの最新記事