LoginSignup
6
3

More than 3 years have passed since last update.

[じぶん用メモ] RailsでPry・DBと仲良くなろう

Last updated at Posted at 2020-10-02

はじめに

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

6
3
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
6
3