アソシエーションを組む時に使う、belongs_to/has_one/has_manyの違いについて。
railsにおいて、アソシエーションを組んでテーブル同士を結びつける時に使うbelongs_to/has_one/has_manyのそれぞれの使い分けについてまとめます。
アプリの概要
メルカリのようなフリマアプリで考えていきます。
まず、userテーブル、itemテーブル、purchaseテーブルの3つのテーブルを設計したとします。
userテーブルでuserの情報を管理します。itemテーブルでは商品の情報を管理します。purchaseテーブルには購入履歴を管理します。以下イメージです。
アソシエションについて
belongs_toメソッド
商品1つに対して、出品者は1人になるためです。
1つの商品に複数人が出品できないため、商品は必ず1人に所属します。
この状態をbelongs_toの関係といいます。
has_oneメソッド
has_oneメソッドは1対1の関係を結ぶメソッドです。
上の図ではitemとpurchaseがそれにあたります。
商品1つに対して、購入履歴は1つになるためです。
親のモデル(今回は商品がなければ、購入履歴がありえないため、itemが親になります。)にhas_oneの記述をします。
子のモデルにbelongs_to(今回はpurchaseが子になります。)の記述を行います。
has_manyメソッド
user側からすると出品する商品(item)は複数あります。
つまり1人のuserは複数のitemを持ちます。
この関係をhas_manyの関係といいます。
このuser1人に対して複数商品がある状態を1対多(has_many)の関係にあるといいます。
まとめ
belongs_toは1対1の関係で子側(後から作られるもの)のモデルに書く。
has_oneは1対1の関係で親側(先に作られるもの)のモデルに書く。
has_many1対多の関係で複数持つ側のモデルに書く。
railsでサーバーが起動しない場合の原因
rails sでサーバーを起動し、ローカル環境でブラウザの確認をする機会が多くあると思います。その時、
A server is already running
とターミナルで出て、ブラウザがずっと読み込み続けて開けない時の原因と対策を記録していきます。
原因
これは一日の作業後にターミナルやサーバーを立ち上げたまま閉じたり、繋げっぱなしにすると起こるようです。
対策
まず、直し方です。
ターミナルにps aux | grep pumaと入力します。
これで状態の確認ができます。すると、
ユーザー名 1245 99.9 2.0 4589056 171840 ?? R 9:55PM 20:58.15 puma 3.12.6 (tcp://localhost:3000) [furima-00000]
ユーザー名 3273 0.0 0.0 4287756 744 s000 S+ 11:51AM 0:00.00 grep puma
このような記述が帰ってきました。
1つ目の記述を見るとlocalhost:3000でfurima-00000が動いています。とのことなので動作をしている番号を消すため
ターミナルにkill 1245と入力します。
その後、ps aux | grep pumaと入力すると、
ユーザー名 3279 0.0 0.0 4268300 696 s000 S+ 11:52AM 0:00.00 grep puma
となり、裏で動いていた処理がなくなりました。
これでrails sすると、正常にサーバーが立ち上がりました。
まとめ
原因はサーバーやターミナルを付けっぱなしにしていること。
対策はサーバーが止まったら、
ps aux | grep puma
で状態確認を行う。
不要なタスクをkill 番号、で消す。
ps aux | grep puma
で動いている処理を再確認する。
1日の作業が終了したら、サーバーを落としてターミナルを切る。電源を落とす。
定期的に起こるようなのでしっかり覚えておきたい。
before_actionの使い方とコードの可読性の上げ方
コントローラーのアクションで下記のような選んだ商品と現在ログイン中のユーザーが同じか確認する記述がありました。何度も同じ記述を繰り返さないためにどうすればいいか記録していきます。
上記の場合、コントローラーのアクションで下記のような選んだ商品と現在ログイン中のユーザーが同じか確認する記述がeditアクションとupdateアクションで出てきます。
コードを簡潔にするためbefore_actionで上記コードをまとめると可読性が上がります。
before_actionは指定したアクションの前に自動で実行する処理を書いておくものです。
before_action+使いまわしたいメソッド名+アクション名で記述します。
まとめたい処理をcurrent_userとメソッド化することでbefore_actionで使えるようになります。
まとめ
before_actionでコードをまとめることで可読性が上がり、修正時も一部分を修正するだけでよいので、できるだけまとめるように心がけたいですね。
文字列の一部を切り取りたい時の書き方。
任意の文字列の最初の2文字を最後尾に持ってきて
その文字を出力するメソッドを作りたい時の書き方。
出力例:
left2("Hello") → lloHe
left2("Hi") → Hi
def left2(str) puts str[2..-1] + str[0..1] end
①str[2..-1]で(配列の1文字目は0のため)3文字目から最後、②str[0..1]で最初の2文字を表しています。これを任意の文字列の最初の2文字を最後尾に持ってくるようにすればいいので、①→②の順で記述すればよい。
全角数字について
テストコードで全角数字でないことを確認したい時に困ったのでメモしておきます。
一般的な数字は半角数字で111などと入力します。
一方、全角数字は111ですが、これは数字ではなく文字扱いになります。
よって、全角数字は"111"のように""や''のクォーテーションで囲む必要があります。
全角数字は普段あまり使われず、調べても出てこないです。
数字は半角だから、全角なら数字ではない扱いになるのか、など仮説を立てて検証するしかなかったようです。
rails db:rollbackでエラーが出てしまい、rollbackできない時の対処方法。
rails db:rollbackができない場合の対処方法をまとめていきます。
1、マイグレーションファイルの変更方法
マイグレーションファイルはエディタ上では書きかえられますが、そのままでは反映されません。コードを変更する前にターミナルで
rails db:rollback
と入力し一度戻して
rails db:migrate:status
と入力し確認すると
上のようになります。(下から順に一つずつdownになります。)downになったファイルを変更し、
rails db:migrate
と入力するとdownのところがupになり修正が反映されます。
2、rails db:rollbackでstatusがdownにならない時
何らかの理由でマイグレーションを消すと
********** NO FILE **********
となり、rails db:rollbackでstatusがdownにならなくなります。
その場合、
1.bundle exec raka db:drop
2.bundle exec raka db:create
3.bundle exec raka db:migrate
4.bundle exec raka db:migrate:status
と順番に打つと
のように********** NO FILE **********が消えます。
その後、
rails db:rollback
と打つと、一番下がdownになり、マイグレーションファイルが変更出来るようになります。