- 投稿日:2020-03-22T12:50:20+09:00
【Rails】データベース関連の知識、操作方法
はじめに
Railsでアプリを開発するにあたって、データベース関連の設計、操作で色々苦労したので、自分の覚えの為にもまとめてみました。
環境
- Ruby 2.5.1
- Rails 5.0.7
そもそもデータベースとは
一定の形式で、「複数で共有、利用すること」と「検索、加工すること」を目的に整理されたデータの集まりの事を指す。プログラミングに限定された用語ではなく、日常生活で使う辞書等もデータベースみたいですね!
データベース種類
- 階層型
- ネットワーク型
- リレーショナル型(RDBと呼ばれ最も主流)
- Oracle Database
- MySQL
- PostgreSQL
- Microsoft SQL Server など
- NoSQL
MySQLを使って開発する事が多かったので、ここからMySQL(リレーショナル型)に絞って話を進めていきます。
リレーショナルデータベース(RDB)、SQLとは
RDBは現在主流のデータベースで、エクセルみたいな表で構成されたデータベース。行と列を持ち、表形式でデータの関係性を示す。SQLを用いたデータのアクセスが可能。
SQL・・・Structured Query Languageの略で、リレーショナルデータベース(RDB)の操作を行うための言語。日本語訳は「構造化された問い合わせ言語」みたいな感じですかね!とにかくデータベースから情報を参照する言語。
データベース設計で意識する事
正規化、アソシエーション、制約の話をまとめていきます。
正規化
正規化・・・データベースのデータ構造をより効率的で重複や無駄のないシンプルな構造にするための手順。正規化の話は複雑ですが以下例です。
×予約情報が重複している為望ましくない
○テーブルを2つに分け予約情報の重複を解消
アソシエーション
アソシエーション・・・テーブル間の関係性をモデルの上の関係として操作できるようにする仕組み。
アソシエーションを利用すると複数のテーブルにまたがるデータ操作もより直感的に利用できる。
【モデルへの書き方】〇〇.rb# 1対多 has_many :モデル名複数形 # 多対1 belongs_to :モデル名単数形 # 1対1 どちらかのモデルにhas_one,もう一方にbelongs_to has_one :モデル名単数形 belongs_to :モデル名単数形 # 多対多 中間テーブルが必要 has_many :中間テーブル名複数形 has_many :モデル名複数形 through: :中間テーブル名複数形制約による安全性
制約とは・・・特定のデータの保存を許さない事。例えば同じニックネームのユーザーを登録できないようにする、名前のデータが空のユーザーを保存を許さない等。主な制約は以下です。
制約種類
- NOT NULL制約・・・空(nil)レコードは保存できない。
- 一意性制約 ・・・同じ値を設定できない。一意性制約をかけるときは、インデックスの作成も必要。 全てのデータを検索しないと、過去のデータと重複しているか判断できない為。
- 主キー制約 ・・・Railsでは主キーはidカラムとして自動で作成(テーブルの一番左のカラム)。
- 外部キー制約 ・・・外部キー制約は、外部キーの対応するレコードが必ず存在しなくてはいけないという制約です。外部キーのカラムに値があっても、その値を主キーとして持つ他のテーブルにレコードが存在する必要あり。
create_users.rb# NOT NULL制約 nameはカラム名,stringはデータ型 t.string :name, null: false # 一意性制約 インデックスとセット usersはテーブル名、emailはカラム名、stringはデータ型 add_column :users, :email, :string add_index :users, :email, unique: true # 外部キー referencesはデータ型 これでuser_idというカラムが生成される t.references :user, foreign_key: trueデータ型種類
- string : 文字列
- text : 長い文字列
- integer : 整数
- float : 浮動小数(実数)
- datetime : 日時
- time : 時間
- date : 日付
- boolean : Boolean
Railsでのコマンド集
ターミナル/マイグレーションファイル<データベース全般> #データベース作成(色んなテーブルを入れる箱の作成) database.ymlの内容に基づく rails db:create #データベース削除 rails db:drop #マイグレーションファイルの適用 rails db:migrate #マイグレーションファイルがどこまで適用されているか確認 rails db:migrate:status #マイグレーションのバージョンを下げる デフォルトでは一つずつ rails db:rollback #マイグレーションのバージョンを複数下げる 例では3段階 rails db:rollback STEP=3 <モデル(テーブル)関連>コマンドでマイグレーションが作成されるので、そこで編集等を行う #モデル(テーブル作成) モデル名は単数形/頭文字を大文字にする rails g model モデル名 #最初からカラム付きでモデルを作成したい時,2行目は例 rails g model モデル名 カラム名:型 rails g model User name:string email:string #既存のモデル(テーブル)にカラムを追加/削除,2行目は例 rails g migration <マイグレーションファイル名> <追加するカラム名:型> rails g migration add_email_to_users email:string #以下マイグレーションファイル(add付きのファイル名でもカラムの削除は行える) # 追加(2行上のコマンドであればマイグレーション作成時からある) add_column :users, :email, :string # 削除(必要に応じて追加) remove_column :users, :gmail, :string # まとめて削除(必要に応じて追加) remove_columns :users, :column_1, :column_2 [, ...] # 追加する場所を指定する場合(必要に応じて追加) # 以下、nameカラムの直後にemailカラムを追加する場合 add_column :users, :email, :string, :after => :name #指定のテーブル削除,2行目は例 rails g migration Dropテーブル名 rails g migration DropUser #既存のテーブル名を変更する,2行目は例 rails g migration Rename変更前テーブル名To変更後テーブル名 rails g migration RenameUserToCustomer #既存のカラムの内容を変更(例.Userモデルのemailカラムに制約をつける場合) rails g migration ChangeColumnToUser #以下マイグレーションファイル # 変更内容 def up change_column :users, :email, :string, null: false end # 変更前の状態 def down change_column :users, :email, :string, null: true endその他の便利なメソッド
外部キー制約が要因で特定のレコードを削除できないエラーが起きる事があると思います。その時はdelete, delete_all, destroy, destroy_allメソッドが大変便利です。
こちらの記事が大変参考になりました。
https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2参考URL
https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2
https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47
- 投稿日:2020-03-22T07:19:04+09:00
Rails アプリを EC2 にデプロイしよう!(デプロイ編)
Rails アプリを Amazon Web Service を使ってデプロイするまでの手順をまとめました。
次の順番でデプロイまで持っていきます。1, 準備編
2, サーバー構築編
3, 環境構築編
4, デプロイ編今回は「デプロイ編」です。
1 ~ 3 を読んでない方は先に読んでください。
Rails アプリを EC2 にデプロイしよう!(準備編)
Rails アプリを EC2 にデプロイしよう!(サーバー構築編)
Rails アプリを EC2 にデプロイしよう!(環境構築編)Gem のインストール
前回までに、アプリのクローンを完了しました。
今回の最初の作業は、gem のインストールです。まずは bundler を設定しましょう。
bundler は本アプリ使用している bundler とバージョンが一致しているものを選択しましょう。[minato@ip-192-168-10-49 ~]$ /var/www/rails/sample_app [minato@ip-192-168-10-49 sample_app]$ gem install bundler 2.1.4 Fetching bundler-2.1.4.gem Successfully installed bundler-2.1.4 Parsing documentation for bundler-2.1.4 Installing ri documentation for bundler-2.1.4 Done installing documentation for bundler after 3 seconds 1 gem installed次に、Gemfile の中身を確認しましょう。
今回は次の gem を想定しています。Gemfilegem 'rails', '~> 5.2.2' gem 'bootsnap', require: false gem 'puma', '~> 3.7' gem 'mysql2', '>= 0.4.10', '< 0.5'確認したら
bundle install
を行いましょう。[minato@ip-192-168-10-49 sample_app]$ bundle _2.1.4_ install --path vendor/bundle --without development:test無事にインストールできれば OK です。
アプリの secret_key_base の設定
次に secret_key_base の設定を行います。
今回はRails 5.2
なので、config/credentials.yml.enc
を読み込むために
config/master.key
をEC2でも作成しましょう。
これがないと本番環境で起動することができません。
- ローカル環境 にある
config/master.key
の中身をコピーします。- サーバー環境 で
config/master.key
を新規作成して先ほどコピーした内容をペーストします。次のコマンドで secret_key_base が確認できれば OK です。
[minato@ip-192-168-10-49 sample_app]$ EDITOR="vim" bundle exec rails credentials:editPuma の設定
次は Puma の設定を行います。
Puma はアプリケーションサーバーの一種です。早速設定していきます。
config/puma.rbcase ENV['RAILS_ENV'] when "production" environment "production" port 3000 threads 16, 16 daemonize true # sample_app の部分は自身のアプリケーションの名前に変更してください。 app_dir = File.expand_path("/var/www/rails/sample_app", __FILE__) bind "unix://#{app_dir}/tmp/sockets/puma.sock" pidfile "#{app_dir}/tmp/pids/puma.pid" state_path "#{app_dir}/tmp/pids/puma.state" stdout_redirect nil, "#{app_dir}/log/puma.stderr.log", true plugin :tmp_restart else environment "development" port 3000 threads 5, 5 pidfile "tmp/pids/puma.pid" state_path "tmp/pids/puma.state" stdout_redirect nil, "log/puma.stderr.log", true plugin :tmp_restart endここら辺は設定ファイルなので、詳細には追いません。
また、設定ファイルの記述が終わったら、次のコマンドも実行してください。[minato@ip-192-168-10-49 sample_app]$ mkdir tmp/sockets
puma.sock
を作成先のディレクトリを作成しています。
これで Puma の設定が完了です。Nginx の設定
お次は Nginx です。「エンジンエックス」と読むそうです。
この Nginx は Web サーバーにあたります。早速下記コマンドを打ち込んでください。
[minato@ip-192-168-10-49 ~]$ cd ~ [minato@ip-192-168-10-49 ~]$ sudo yum install nginx [minato@ip-192-168-10-49 ~]$ sudo vim /etc/nginx/conf.d/sample_app.confvim コマンドで作成した nginx の設定ファイルを次のように記述します。
/etc/nginx/conf.d/sample_app.conf# アクセスログ・エラーログの出力先を設定する # sample_app の部分は自身のアプリケーションの名前に変更してください error_log /var/www/rails/sample_app/log/nginx.error.log; access_log /var/www/rails/sample_app/log/nginx.access.log; upstream puma { # puma.sock の場所を指定する # sample_app の部分は自身のアプリケーションの名前に変更してください server unix:///var/www/rails/sample_app/tmp/sockets/puma.sock; } server { listen 80; # server_name を設定します。自身のパブリックDNSに変更してください。 server_name ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com; client_max_body_size 500M; keepalive_timeout 5; # パブリックページの場所をここで設定します。 # sample_app の部分は自身のアプリケーションの名前に変更してください root /var/www/rails/sample_app/public; location / { try_files $uri $uri/index.html $uri.html @app; } location @app { proxy_read_timeout 300; proxy_connect_timeout 300; proxy_redirect off; client_max_body_size 1G; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://puma; } # Rails のエラーページを表示する # sample_app の部分は自身のアプリケーションの名前に変更してください error_page 500 502 503 504 /500.html; location = /500.html { root /var/www/rails/sample_app/public; } }ここも設定ファイルなので詳細には追いません。
また、AWSが生成するドメイン名が
ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com
と大変長いので、次のコマンドを実行して設定を変えます。$ sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old $ sudp vim /etc/nginx/nginx.confnginx.conf# ... http { # ... sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_names_hash_bucket_size 128; # これを追記 # ... }最後に、次のコマンドを実行してください。
[minato@ip-192-168-10-49 conf.d]$ cd /var/lib [minato@ip-192-168-10-49 lib]$ sudo chmod -R 775 nginxpost メソッドでもエラーが出ないようにするためのものです。
これにて Nginx の設定完了です。MySQLの設定
次は DB です。
アプリケーションの DB が MySQL で作成されている前提で話を進めていきます。まずは database の設定を行います。
[minato@ip-192-168-10-49 sample_app]$ vim config/database.yml設定内容は次のとおりです。
config/database.ymlproduction: <<: *default adapter: mysql2 port: 3306 database: sample_app_production username: root password: encoding: utf8 charset: utf8 collation: utf8_general_ci保存したら次のコマンドを実行していきましょう。
# mysql を起動 [minato@ip-192-168-10-49 sample_app]$ sudo service mysqld start # mysql.sock を /tmp に移動する [minato@ip-192-168-10-49 sample_app]$ ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock # 本番環境用の db を作成する [minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec rake db:create # 本番環境用の db の migrate を実行する [minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec rake db:migrate
seed
を予め設定する場合はこのタイミングで実行してください。Rails アプリの起動
このコマンドで puma を起動しましょう。
これで Rails アプリが起動します。[minato@ip-192-168-10-49 sample_app]$ RAILS_ENV=production bundle exec pumaインターネットからアクセス出来る様に
次のコマンドで nginx を起動します。[minato@ip-192-168-10-49 sample_app]$ sudo service nginx start自身のパブリックDNSを使用してブラウザからアクセスしてみましょう
http://ec2-52-198-194-39.ap-northeast-1.compute.amazonaws.com/
無事にアクセスできれば OK です。
停止方法
最後に停止方法について記述しておきます。
$ sudo service nginx stop$ bundle exec pumactl halt最後に
これでデプロイを完了することができました。
でも、まだアクセス出来てない方もいるかと思います。
そんな方はググったり、質問したりして問題解決を頑張ってください。
当たりが強いエンジニアもいますが、優しく教えてくれるエンジニアもいます。自分は大学一回生でこのデプロイ作業を初めて行いましたが、完了するのに1週間もかかりました。
それでも大学の先輩に質問したり、頑張って英語の公式ドキュメントを読んだり、
ひたすらググったりすることでなんとかデプロイを完了しました。このデプロイ経験で多くの知識や経験を得ました。
特に、根気よく問題解決する精神は鍛えられました。根気よく、適度に休憩をとりながら、デプロイ作業を頑張ってください。