Open14

データベース作成

かいかい

データベースは、データを整理して管理するために表のような形式を使っています。
この表のことを「テーブル」と言います。
例えば、投稿データを管理する「postsテーブル」があるとします。
横に並んだ各行が、1つ1つの投稿データを表しており、この1行のデータを「レコード」と呼びます。
また、縦に並んだ部分は投稿データの「タイトル」や「内容」といった情報を管理するもので、
これを「カラム」と言います。

簡単に言うと、
テーブルはデータを整理する表で、
行(レコード)は個々のデータを、
列(カラム)はそのデータの項目を表しているということです。


では投稿に対応したテーブルを作成しよう!

かいかい

まず、データベースに変更を指示するための「マイグレーションファイル」を作成しましょう。
マイグレーションファイルは、
データベースのテーブルやカラムを追加・変更するために使うファイルです。

たとえば、投稿データを管理する「postsテーブル」を作成したい場合、

rails g model Post content:text

というコマンドを実行します。このコマンドを実行すると、
postsテーブルを作成するマイグレーションファイルが自動的に作成されます。
(テーブルを作成する場合は複数形でなくposts⇒Postと単数にする)

ここで、「content」の部分について説明します。
content」はテーブルに追加するカラムの名前で、投稿の内容を意味しています。
text」は、データの型を表していて、
「長い文字列」を保存できるようにする指定です。
このように、マイグレーションファイルでテーブルやカラムを定義することで、
データベースに適切な形で情報を保存できるようになります。


もう少し詳しく・・・


rails g model ○○○○ □□□:△△△

○○○○⇒テーブル名(モデル名でもある?)
□□□⇒カラム名
ここは任意の名前に変更できる
△△△⇒データ型
これも自由に変更できます。Railsでは、以下のような一般的なデータ型がサポートされています:

基本的なデータ型

string

短い文字列(通常255文字まで)。名前やタイトルなどに使用。

例: rails g model User name:string

text

長い文字列(文字数に制限が少ない)。記事の本文やコメントなどに使用。

例: rails g model Post content:text

integer

整数値。数値のIDやカウントに使用。

例: rails g model Product stock:integer

boolean

真偽値(true または false)。スイッチやフラグに使用。

例: rails g model Task completed:boolean

decimal

少数点を含む数値。金額や精度の高い数値に使用。
precision(桁数)やscale(小数点以下の桁数)も指定できる。

例: rails g model Product price:decimal{8,2}(8桁中、小数点以下2桁)

float

浮動小数点数。近似値を使う計算に使用。

例: rails g model Measurement temperature:float

datetime

日時。日付と時間を扱う。Rails 5.0以降は、timestampがデフォルトで使用される場合もある。

例: rails g model Event start_time:datetime

date

日付のみ。時間を含まず、誕生日や締め切りに使用。

例: rails g model User birthday:date

time

時間のみ。日付を含まず、特定の時間のみに関連するデータに使用。

例: rails g model Appointment start_time:time

binary

バイナリデータ。画像やファイルなどの生データに使用。

例: rails g model FileUpload data:binary

より高度なデータ型

primary_key

テーブルの主キー(ID)。通常、自動で生成されるため手動で指定することは少ない。

bigint

大きな整数。integerでは表現できないほど大きな数値に使用。

例: rails g model LargeNumber count:bigint

json / jsonb

JSON形式のデータを格納する。jsonbはバイナリ形式でより効率的に扱える。

例: rails g model Settings preferences:jsonb

uuid

ユニークな識別子としてUUIDを格納するカラム。
セキュリティの観点からIDの代わりに使われることがある。

例: rails g model Order order_id:uuid

array

配列データ。PostgreSQLでサポートされている型。

例: rails g model User hobbies:string, array:true (PostgreSQL専用)


かいかい

では今回は、

rails g model Post comment:text

を実行!

(相変わらずスペルミスをしてたけど・・・せいこう!)

これでデータベースに変更を指示するファイルが完成した
(マイグレーションファイルを作成しましたってこと)

次に

rails db:migrate

コマンドを実行

Gemfileのbigdecimalとmutex_mに関する警告が表示されているため、

gem 'bigdecimal'
gem 'mutex_m'

を依存関係に関係なく動作する必要のある基本的なライブラリのため、
グローバルな部分(groupの外側)に配置します。

これでテーブル作成完了!
目視で確認したい・・・

かいかい

このテーブルの使い方は?

Postテーブルを操作するためのモデルがあるから。それを
クラスを用いてデータベースを使用する!

・・・どういう意味ぃ?


app/modelsフォルダの中を確認しよう



postモデルが作成されていた!
(「rails g model」コマンドによって、Postモデルが定義されたファイル「post.rb」が作成された)

よく見てみると
ApplicationRecordをPostクラスが継承している!
⇒どういう意味?


Active Recordの機能を利用できる

ApplicationRecord は、RailsのActiveRecord::Baseを継承しているため、
PostクラスはActiveRecordの機能を利用できます。これにより、
Postモデルはデータベースのレコードをオブジェクトとして扱うことができます。
例えば、次のようなメソッドが利用可能になります:

CRUD操作:

Post.create / Post.new / Post.save でレコードを作成・保存できる。
Post.find / Post.where でレコードを検索できる。
Post.update / Post.destroy でレコードを更新・削除できる。

バリデーション:

validates :attribute, presence: true のように、
モデルの属性にバリデーションを設定できます。

アソシエーション:

has_many :comments や belongs_to :user など、他のモデルとの関係を定義できます。


PostがApplicationRecordというルールのような世界に入るって認識かな

かいかい

コンソールを使い始めた!!

rails console

を使ってテーブルに投稿内容を保存していこう。

quit

これで終了させれる

コンソールで変数を定義する
(Post モデルを使って、データベースの posts テーブルに、データを追加してみる)

posts テーブルにデータを追加する時は
① new メソッドで Post モデルのインスタンスを作成
② posts テーブルに保存

かいかい

① new メソッドで Post モデルのインスタンスを作成

コンソールを起動後

post9 = Post.new(content:"Hello world")

と入力することでPost モデルのインスタンスを作成ができる(中身はcontentが「Hello world」である)

**
② posts テーブルに保存**

このインスタンスをテーブルに保存するにはsaveメソッドを使う

post9.save
かいかい

データベースを使えるようになったけど
これがどうやって投稿ページに反映させれる?

データの取り出し方を調べよう

かいかい

テーブルに保存されている全てのデータを取得するには、
Post.all」を使用します。これにより、
「postsテーブル」に保存されているすべてのレコードが取得できます。
⇒「Post.all」では、テーブルにある全てのデータが配列で取得できる


配列ということは・・・

Post.all [0]

上記の様に指定すれば、インデックス番号で1つの要素を取得できる
(Post.all[0]  = Post.first で取得したときと同じ形のデータ)

Post.all[0].content

上記の様にカラム名を指定すれば、その内容を習得できる(idならidみたいな感じ)

かいかい
posts = Post.all

で変数に定義すれば、postsにすべてのPostが入り込む的な感じになるので

Post.all[0].content

これで配列番号が0のcontentが呼び出せるし、数字を変えれば、それに対応した出力になる

かいかい

ではデータベースの内容をビューに反映させるには?

かいかい

postsコントローラのindexアクション内で、
@postsにPost.allで取得したデータを代入します。
これにより、@postsには「postsテーブル」のすべての投稿データが格納されます。


なるほど・・・そこでコントローラがきますか・・・

この中で定義された変数はビューに反映されるのは、データベースを使う前に
eachを試しに入れた時に確認済み

では@postsにPost.allで取得したデータを代入します。


データベースにはデータはないので消えるはず
ちゃんと消えた!
(もともと違う変数名でしていしていたのでeachの変数を@texts⇒@postsに変更)

かいかい

コンソールを立ち上げて入力を始める

 post1 = Post.new(content:"ドラッグストアの裏側が体験できて楽しかったです")

これだと

(irb):1:in `<main>': unknown attribute 'content' for Post. (ActiveModel::UnknownAttributeError)

          raise UnknownAttributeError.new(self, k.to_s)
          ^^^^^

このエラーメッセージは、Postモデルに「content」というカラムが存在しないことが原因。
rails consoleで実行したコードに「comment」というカラム名を使用しているので、
おそらくマイグレーションファイルやモデルでカラム名が「comment」になっているはず。


修正して

post1 = Post.new(comment:"ドラッグストアの裏側が体験できて楽しかったです")

これで大丈夫そうだった

post1.save

保存を忘れていたので実行

Post.all

データが入力されている事を確認できた

しかし!!


へんな数字でコメントが反映されない・・・


index.html.erbでPostモデルのcommentカラムの内容を表示するには、
<%= comment %>の代わりに<%= comment.comment %>を使う必要があります。
これにより、Postオブジェクトのcomment属性を正しく表示できます。
修正したコードは以下のようになります。


<%= comment.comment %>ってなんでやろ


comment.comment という記述のそれぞれについて解説します。

comment (1つ目)
最初の comment は、each ループのブロック変数として使われています。@posts.each do |comment| というコードでは、@posts に格納されている Post オブジェクトのコレクションを1つずつ取り出し、ブロック変数 comment に代入しています。

この場合、@posts は Post.all などのメソッドで取得された Post モデルのオブジェクトを含む配列(または ActiveRecord::Relation)です。そのため、ループ内の comment は個々の Post オブジェクトを指しています。

comment (2つ目)
2つ目の comment は、Post モデルのカラム(属性)の名前を指しています。Post モデルには comment というカラムが存在しており、そのカラムには各投稿のコメント内容が保存されています。

comment.comment の意味
最初の comment は、Post オブジェクト(つまり、1つの投稿)を表します。
2つ目の comment は、その Post オブジェクトの comment 属性を指しています。
したがって、comment.comment は、「その Post オブジェクトの comment カラムの値を取得する」という意味になります。


納得