はじめに
RailsでPryを使ってDBの操作をする時に
必要なコマンドや考え方を自分用メモとして残します。
環境
MacOS Mojave
Ruby 2.6.4
Rails 6.0.3.3
Vue 2.6.12
Webpack 4.44.2
yarn 1.22.5
Docker 2.3.0.5
VScode
環境構築
Dockerを用いたVue Rails6環境構築については以下にまとめています。
リンク:Rails6 Vueの連動方法(環境構築から)
モデルとDBのマイグレーション関連
Dockerコンテナは上げておきます。
Docker-compose up
Articleモデルの作成
Docker-compose exec web rails g model Article name:string content:text
Running via Spring preloader in process 207
invoke active_record
create db/migrate/20200926174356_create_articles.rb
create app/models/article.rb
invoke test_unit
create test/models/article_test.rb
create test/fixtures/articles.yml
Commentモデルの作成
Docker-compose exec web rails g model Comment comment:text
Running via Spring preloader in process 276
invoke active_record
create db/migrate/20200926174846_create_comments.rb
create app/models/comment.rb
invoke test_unit
create test/models/comment_test.rb
create test/fixtures/comments.yml
DBへの反映
Docker-compose exec web rails db:migrate
== 20200926174356 CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0505s
== 20200926174356 CreateArticles: migrated (0.0519s) ==========================
== 20200926174846 CreateComments: migrating ===================================
-- create_table(:comments)
-> 0.0296s
== 20200926174846 CreateComments: migrated (0.0310s) ==========================
DBのステータス確認
Docker-compose exec web rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20200926174356 Create articles
up 20200926174846 Create comments
DBのバージョン
Docker_Rails6_Vue hiroki$ Docker-compose exec web rails db:version
Current version: 20200926174846
Schema.rbでもバージョン確認
schema.rb
ActiveRecord::Schema.define(version: 2020_09_26_174846) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "articles", force: :cascade do |t|
t.string "name"
t.text "content"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "comments", force: :cascade do |t|
t.text "comment"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
DBのロールバック
Docker-compose exec web rails db:rollback STEP=2とすると[+1]downされる。
つまり
Docker-compose exec web rails db:rollback STEP=1
と
Docker-compose exec web rails db:rollback
は同じ
Docker-compose exec web rails db:rollback
== 20200926174846 CreateComments: reverting ===================================
-- drop_table(:comments)
-> 0.0104s
== 20200926174846 CreateComments: reverted (0.0156s) ==========================
DBのステータス確認
マイグレーションファイルの削除やDBのカラムの追加などはdown時に実施する必要がある。
一般的にDBのてカラムの追加は別にマイグレーションファイルを作成して記述する。
Docker-compose exec web rails db:migrate:status
database: myapp_development
Status Migration ID Migration Name
--------------------------------------------------
up 20200926174356 Create articles
down 20200926174846 Create comments
Docker-compose exec web rails db:migrateをして戻しておきます。
Pryの起動
Pryを起動する
Docker-compose exec web rails c
Running via Spring preloader in process 1191
Loading development environment (Rails 6.0.3.3)
[1] pry(main)>
articleオブジェクトを新規作成
pry(main)> @article = Article.new
=> #<Article:0x0000555d5c5340a8 id: nil, name: nil, content: nil, created_at: nil, updated_at: nil>
pry(main)>
articleオブジェクトに値を入れる
pry(main)> @article.name = "記事1"
=> "記事1"
pry(main)> @article.content = "記事の内容です"
=> "記事の内容です"
articleオブジェクトがバリデーションに合格するか
pry(main)> @article.valid?
=> true
articleオブジェクトをDBに保存する。
pry(main)> @article.save!
(0.5ms) BEGIN
Article Create (8.5ms) INSERT INTO "articles" ("name", "content", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "記事1"], ["content", "記事の内容です"], ["created_at", "2020-09-26 18:18:00.150412"], ["updated_at", "2020-09-26 18:18:00.150412"]]
(4.1ms) COMMIT
=> true
postgresに接続する。
docker-compose exec db psql -U postgres -d myapp_development
psql (12.4 (Debian 12.4-1.pgdg100+1))
Type "help" for help.
myapp_development=#
データベースのリストを表示
myapp_development=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------------+----------+----------+------------+------------+-----------------------
myapp_development | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
myapp_test | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
接続したDBのテーブルを表示
myapp_development=# \d
List of relations
Schema | Name | Type | Owner
--------+----------------------+----------+----------
public | ar_internal_metadata | table | postgres
public | articles | table | postgres
public | articles_id_seq | sequence | postgres
public | comments | table | postgres
public | comments_id_seq | sequence | postgres
public | schema_migrations | table | postgres
(6 rows)
テーブルのカラムを表示
myapp_development=# \d articles
Table "public.articles"
Column | Type | Collation | Nullable | Default
------------+--------------------------------+-----------+----------+--------------------------------------
id | bigint | | not null | nextval('articles_id_seq'::regclass)
name | character varying | | |
content | text | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
Indexes:
"articles_pkey" PRIMARY KEY, btree (id)
テーブルのカラムのデータを表示
myapp_development=# select * from articles ;
id | name | content | created_at | updated_at
----+-------+----------------+----------------------------+----------------------------
1 | 記事1 | 記事の内容です | 2020-09-26 18:18:00.150412 | 2020-09-26 18:18:00.150412
(1 row)
Pryで作成したデータが入っていますね。
モデルの関連付け
Articleを親、Commentを子として関連づける
article.rbを以下に書き換え
class Article < ApplicationRecord
has_many :comments
end
comment.rbを以下に書き換え
class Comment < ApplicationRecord
belongs_to :article
end
関連付けのマイグレーションファイルを追加
docker-compose run web rails g migration Add_Article_Id_To_Comment
Running via Spring preloader in process 68
invoke active_record
create db/migrate/20200926184159_add_article_id_to_comment.rb
作成されたマイグレーションファイルを以下に修正
単数形複数形、テーブルの位置を注意する。
class AddArticleIdToComment < ActiveRecord::Migration[6.0]
def change
add_reference :comments, :article, foreign_key: true
end
end
postgresに接続する。
docker-compose exec db psql -U postgres -d myapp_development
psql (12.4 (Debian 12.4-1.pgdg100+1))
Type "help" for help.
myapp_development=#
commentsテーブルにarticles_idが追加されていることを確認する。
myapp_development=# \d comments
Table "public.comments"
Column | Type | Collation | Nullable | Default
-------------+--------------------------------+-----------+----------+--------------------------------------
id | bigint | | not null | nextval('comments_id_seq'::regclass)
comment | text | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
article_id | bigint | | |
Indexes:
"comments_pkey" PRIMARY KEY, btree (id)
"index_comments_on_articles_id" btree (articles_id)
Foreign-key constraints:
"fk_rails_d8ed532d4e" FOREIGN KEY (articles_id) REFERENCES articles(id)
pryを起動する。
comment = Comment.new
=> #<Comment:0x00007f1d8c4f2490 id: nil, comment: nil, created_at: nil, updated_at: nil, article_id: nil>
commentsモデルにデータを格納する。
comment.comment = "This is Comment"
=> "This is Comment"
comment.articles_id = 1
=> 1
モデルで作成したインスタンスをDBに格納できるかバリデーションを行う。
comment.valid?
=> true
インスタンスをデータベースに保存する。
comment.save
(0.6ms) BEGIN
Comment Create (17.2ms) INSERT INTO "comments" ("comment", "created_at", "updated_at", "article_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["comment", "This is Comment"], ["created_at", "2020-10-02 12:50:20.046429"], ["updated_at", "2020-10-02 12:50:20.046429"], ["article_id", 1]]
(3.3ms) COMMIT
=> true
ID1のArticleインスタンスを作成する。
article = Article.find(1)
Article Load (3.6ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<Article:0x00007f1f0c612a38
id: 1,
name: "記事1",
content: "記事の内容です",
created_at: Sat, 26 Sep 2020 18:18:00 UTC +00:00,
updated_at: Sat, 26 Sep 2020 18:18:00 UTC +00:00>
ID1のArticleインスタンスに関連しているCommentsのデータを取得する。
commnet = article.comments
=> Comment Load (2.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = $1 [["article_id", 1]]
[#<Comment:0x00007f1f0c81a088
id: 1,
comment: "This is Comment",
created_at: Fri, 02 Oct 2020 12:50:20 UTC +00:00,
updated_at: Fri, 02 Oct 2020 12:50:20 UTC +00:00,
article_id: 1>]
もう一つCommentインスタンスを作成する。
commnet = Comment.new
=> #<Comment:0x00007f1f0ca3c780 id: nil, comment: nil, created_at: nil, updated_at: nil, article_id: nil>
バリデーションを行う。
commnet.valid?
=> false
バリデーションエラー時のエラーを取得する。
commnet.errors
=> #<ActiveModel::Errors:0x00007f1f0caa9d58
@base=#<Comment:0x00007f1f0ca3c780 id: nil, comment: nil, created_at: nil, updated_at: nil, article_id: nil>,
@details={:article=>[{:error=>:blank}]},
@messages={:article=>["must exist"]}>
以上でD