LoginSignup
1
0

More than 1 year has passed since last update.

インフラエンジニアがRubyでAPI作ってみた②

Posted at

前置き

前回の記事に引き続き、今回もRubyでAPIを作成していきます。
Docker Desktop,SequelAce, Rubyがインストールされている方は同じように作ることができます。

参考記事:

今回は前回よりも少しだけ難易度をあげて、
①ローカルにMySQLコンテナを作る。(アクセスできることを確認する)

②ローカルでAPIを作る。(DBに値を登録する。)

③コンテナ内のDBを参照してみる。

といった流れで進めようと思います。

①ローカルにMySQLコンテナを作ってアクセスしてみる。

まずは今回作成する一連のファイルを配置するためにディレクトリを切っていきます。

$ mkdir API_sample

作成したディレクトリに移動します。

$ cd API_sample

このディレクトリ直下にdocker-compose.ymlファイルを作成します。

$ touch docker-compose.yml
docker-compose.yml
version: '3.8'
services:
  mysql:
    image: mysql:8.0
    volumes:
      - ./tmp/mysql:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=********

version: '3.8'はdocker-compose.ymlの書式のバージョンを指定しています。
services:の部分に起動させるコンテナを記述します。
今回はDBのコンテナだけを起動するため、このような記述になっています。
tmp/mysqlディレクトリをコンテナ内の/var/lib/mysqlディレクトリとするように指定しています。(後述)
コンテナ内部にはMySQLの8.0verを作成し、3306ポートから接続しますという意味になります。
パスワードは今回生意気にもマスクしてみます。笑

またMySQLのデータを格納しておくためのディレクトリも作成しておきます。

$ mkdir tmp/mysql

下記のコマンドで、実際にMySQLに接続してみます。

$ mysql -h 127.0.0.1 -u root -p

スクリーンショット 2022-04-24 1.45.20.png

無事MySQLに接続することができました。

スクリーンショット 2022-04-24 14.56.50.png

きちんとDBが作成されていることがわかります。

Gemfileとdatabase.ymlを書き換えて、rails⇨コンテナ内のMySQLに接続できるようにする。

デフォルトではsqlite3を利用する設定になっているため、MySQLを使うように設定しなおします。

gem 'sqlite3', '~> 1.4' # この行を削除
gem 'mysql2' # この行を追加

config/database.ymlを書き換えます。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_bin
  host: <%= ENV['MYSQL_HOST'] || '127.0.0.1' %>
  port: <%= ENV['MYSQL_PORT'] || 3306 %>
  username: <%= ENV['MYSQL_USER'] || 'API_user' %>
  password: <%= ENV['MYSQL_PASSWORD'] || '*********' %>
  database: API_dev

development:
  <<: *default

test:
  <<: *default
  database: API_test

production:
  <<: *default
  database: API

これでrails⇨MySQLコンテナに接続できます。

dbにsetup_for_dev.sqlというファイルを作成して以下のように記述します。

setup_for_dev.sql
CREATE USER IF NOT EXISTS API_user IDENTIFIED BY '********';

CREATE DATABASE IF NOT EXISTS API_dev DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

GRANT ALL PRIVILEGES on API_dev.* to API_user;

CREATE DATABASE IF NOT EXISTS API_test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

GRANT ALL PRIVILEGES on API_test.* to API_user;

mysqlコマンドでファイルを読み込んで実行します。

$ mysql -h 127.0.0.1 -u root -p < ./db/setup_for_dev.sql
Enter password: 

MySQLにuserとDBを作成し,権限付与を実行することができました。

②ローカルにAPIを作る。(値を登録する。)

modelを作成します。

$ rails g model Category id:bigint name:string

参考記事にしたがってideaモデルを作成します。

$ rails g model Idea id:bigint category_id:bigint body:text

modelを作成したら、マイグレーションを実行します。下記のような文言が表示されたら成功しています。

$ rails db:migrate
$ rails db:migrate
== 20220424104105 CreateCategories: migrating =================================
-- create_table(:categories)
   -> 0.0536s
== 20220424104105 CreateCategories: migrated (0.0537s) ========================

== 20220424104517 CreateIdeas: migrating ======================================
-- create_table(:ideas)
   -> 0.0378s
== 20220424104517 CreateIdeas: migrated (0.0378s) =============================

modelの定義をしていきます。

model/category.rb
class Category < ApplicationRecord
  has_many :ideas
end
model/idea.rb
class Idea < ApplicationRecord
  belongs_to :category
end

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

$ rails g controller categories
$ rails g controller ideas

続いてルーティングを書いていきます。

config/routes.rb
Rails.application.routes.draw do
  resources :categories, only: [:index, :create]
  resources :ideas, only: [:index, :create]
end

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

categories_controller.rb
class CategoriesController < ApplicationController
  def index
    categories = Category.all
    render json: categories, each_serializer: CategorySerializer, include: [:ideas]
  end

  def create
    category = Category.new(category_params)
    if catgory.save
      render json: { status: 'SUCCESS', data: category }
    else
      render json: { status: 'ERROR', data: category.errors }
    end
  end

  private

  def category_params
    params.require(:category).permit(:name)
  end
end

一覧を取得し、新たに作成するアクションを定義します。
もう一つも作成し、

ideas_controller.rb
class IdeasController < ApplicationController
  def index
    ideas = Idea.all
    render json: ideas, each_serializer: IdeaSerializer, include: [:category]
  end

  def create
    category = Category.new(category_params)
    idea = Idea.new(idea_params)
    if Category.exists?(name: params[:category][:name])
      idea_body.save
    else
      render json: ideas
    end
  end

  def idea_params
    params.require(:idea).permit(:body)
  end
end

としておきます。

Gemfileに以下を追加して $ bundle install します。

gem 'active_model_serializers'

モデルを編集していきます。

class CategorySerializer < ActiveModel::Serializer
  attributes :id, :name, :created_at
  has_many :ideas
end
class IdeaSerializer < ActiveModel::Serializer
  attributes :id, :body
  belongs_to :category
end

Gemfileに以下を追加します。

gem 'faker'
$ bundle install
db/seeds.rb
  5.times do
  name = Faker::Construction.subcontract_category
  Category.create!(name: name)
end

10.times do
  category_id = rand(1..3)
  body = Faker::Food.dish
  Idea.create!(category_id: category_id, body: body)
end

無事データが格納されているか確認してみましょう。

③SequelAceでコンテナ内のDBを参照してみる。

SequelAceを起動します。
画像のような表示がされます。
スクリーンショット 2022-04-24 23.03.29.png

確認してみたところ、無事データが格納されていることが分かりました!!
スクリーンショット 2022-04-24 23.01.43.png

1
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
1
0