PF作るに当たって覚えたことの整理 2020.2.7
- if文でなく、or演算で値を代入する ||
- while end の中で i++を使ってエラーにハマった話
- エラーメッセージの表示のさせ方
- 外部キー制約でデータを削除できなくなった話
- カラムを配列で定義しようとしたものの、デメリットがある為やめた話
if文でなく、or演算で値を代入する ||
rails tutorialにも記載ありますが、
変数 = データA || データB
としておけばデータAがあればデータAを変数に代入。もしなければデータBを代入する。というコードを書けます。
例)
@post = Post.where(user_id: @user.id) || Post.new(post_params)
上記で、user_idが@user.idに適合するpostを。
なければ新しくpostを生成する。
というコードをすっきり書けます。
while end の中で i++を使ってエラーにハマった話
unexpected end_of_input
expecting end
と出てくるので、
「これってendが足りなかったり、多い時に出てくるエラーだよなぁ」
と思ってendを数えて見たのですが、合ってる。。
試しにwhile~ end を消してみると、うまくいく。
ということはwhile ~ end の記述がおかしい。と思い、見てみるも構文通り。。
っていうかwhile自体、そんな難しい構文じゃないし。
で、結果からいうと
while i <= 10 do
i++
end
という記述になっていたから。
これを
while i <= 10 do
i+= 1
end
こう書き換えて解決。
エラーメッセージの表示のさせ方
rails tutorialでflashを使ってエラーメッセージを表示させる方法をやったなぁ。
と思い、PFにも適用することに。
controllerのflashを作りたい箇所で
controller.rb
flash[:danger] = "表示させたいエラー文"
を記述
application.html.erb
<% flash.each do |message-type, message| %>
<div class="alert alert-<%= message-type %>"><%= message %></div>
<% end %>
をbodyの中に記述。
上記では
[:danger]
を使用しているが、他にも
[:success]
[:info]
[:warning]
を使っても自動的にスタイルがあたる。
外部キー制約でデータを削除できなくなった話
テストで作った、Chatデータを削除しようとしたら
・・・foreign key constraint fails
というエラー文が出てきて、削除できない。。
ちなみに、モデルの関連づけでいうと
User.rb
has_many :chats, foreign_key: :user_id
Shop.rb
has_many :chats, foreign_key: :shop_id
Chat.rb
belongs_to :shop
belongs_to :user
has_many :messages, foreign_key: :chat_id
Message.rb
belongs_to :chat
となってます。
外部キー制約
調べてみると、外部キー制約の関係で削除できないみたい。
外部キー制約については詳しく解説してある記事がたくさんあるので、そちらを参照して頂ければと思いますが、上記の例でいうと
messageはchatと関連付けられていて、Messageテーブルのデータには必ずそれぞれchat_idが入っています。
が、あるchatを勝手に削除してしまうと、chat_idが空のmessageができてしまうので、それを防ぐためのものです。
dependent: :destroy
外部キー制約の関係で、chatを削除する際にエラーが起きてしまっていました。
エラーを出さずに削除するために それぞれにdependent: :destroy を追記して、無事解決しました。
User.rb
has_many :chats, foreign_key: :user_id, dependent: :destroy
Shop.rb
has_many :chats, foreign_key: :shop_id, dependent: :destroy
Chat.rb
belongs_to :shop
belongs_to :user
has_many :messages, foreign_key: :chat_id, dependent: :destroy
Message.rb
belongs_to :chat
optional: true
エラーを解決のために色々な記事を調べていたら、
belongs_to :chat, optional: true
というようにoptional: trueを記述しているコードがあって、optional: true って、なんじゃらほい?と思って調べてみると、どうやらbelongs_toの外部キーのnilを許可するもの。みたいです。
つまり、外部キーがnilであってもDBに保存されるということですね。
カラムを配列で定義しようとしたものの、デメリットがある為やめた話
一緒に勉強している仲間から「カラムを配列の形で保存している」と聞き(serialize)、そういうことが出来るのか!と思った自分は、早速自分のポートフォリオでもその技を活用しようとしました。
ただ、よくよく調べてみるとデメリットがあり、要約すると
「serializeを使うと、実際の保存はYAMLまたはJSONで保存されることになり、ある日、急にrailsの都合で形式が変わった際に手動でserializeを使っていたデータを書き換えなければいけなくなる」
「仕様変更(型変更)に弱い」
「遅くなる」
といったところです。
詳しくは下記で解説してくれてます。
ActiveRecord serialize / store の甘い誘惑を断ち切ろう - Qiita
ので、配列にして保存したかったのは数字を文字列化したもので、それを取り出した際にviewに順番に貼り付けていく。ということをしたかっただけなので、
いったん配列の形のまま、データに文字列として保存し、
”[”10”, ”11”, ”12”, ”13”]"
それを取り出した際にsplitで分割して、最初と最後についてしまう"[", " ]"を削除することにしました。
["10", "11", "12", "13"]
とちゃんと配列として再び扱えるようになりましたとさ。