サマリ
- マイクロソフトの表示、投稿、削除
- モデルの関連付け(
has_many
およびbelongs_to
) - モデルを使ったレコードの取得(取得条件、並び順、取得件数の指定)
- ラムダ式 (Stabby lambda) を使ったProcオブジェクトの生成
- モデルの関連付け(
- Homeページの動的な出し分け
- CarrierWaveを使った画像ファイルのアップロード
- ImageMagick(+MiniMagick)を使った画像ファイルのリサイズ
- 本番環境でのfogを使ったS3への画像アップロード
ポイント
-
rails generate model
の際、references
を指定するとFKの指定を行ってくれる
e.g. rails generate model Micropost content:text user:references
を実行した場合
class Micropost < ApplicationRecord
belongs_to :user
end
-
モデルの関連付けを行うと、1対Nの1側からN側のオブジェクトを生成することができ、N側のオブジェクトには1側のオブジェクトのidが設定される。
- e.g.
user.microposts.create
-
user.microposts.create!
=> !をつけると生成失敗時に例外を発生させる -
user.microposts.build
-
build
メソッドはオブジェクトを返すがデータベースに反映はしない
-
- e.g.
-
モデル内で
default_scope
を指定することで、並び順を指定することができる
default_scope -> { order(created_at: :desc) }
- ->というラムダ式は、ブロックを引数に取り、Procオブジェクトを返す
- Procオブジェクトは、callメソッドが呼ばれたとき、ブロック内の処理を評価する
- モデルの関連付けをした1対多の1側に
dependent: :destroy
を付与しておくと、1側のオブジェクトが削除された際に、多側のオブジェクトも一緒に削除される - orderメソッド、takeメソッドを使って取得するレコードの並び順と件数を指定できる
User.order(:created_at).take(6)
- whereメソッドでレコードの取得条件を指定できる。?句を使うことで、変数をエスケープし、SQLインジェクションを防ぐことができる。
def feed
Micropost.where("user_id = ?", id)
end
- フォーム内でバリデーションエラーがあった場合、form_forのブロック変数のobject属性にエラーが入る
- errorパーシャルなどにrenderから変数を引き渡す場合、第二引数にハッシュを指定する
e.g.
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<% end %>
<% if object.errors.any? %>
<div id="error_explanation">
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
renderには以下の使い方がある
- 引数ががアクション名(new, editなど) => アクションに対応したerbの描画
- 引数がパーシャル => パーシャルの描画(第二引数に与えた変数をパーシャル内で使用できる)
- 引数がインスタンス変数 => インスタンス変数に対応したパーシャルを探して描画
- e.g.
render @feed_items
で@feed_itemsの中身がmicropostであれば_micropostパーシャルを探して描画
- e.g.
-
フォームが含まれる画面を描画する際は、form_for(@インスタンス変数)の@インスタンス変数をbuildして空のオブジェクトを用意してから描画する必要がある。
-
フォームが送信されたら改めてparamsから取得した値を使用して@インスタンス変数をbuildしsaveする。
-
erb内の
link_to
メソッドにdata: { confirm: "You sure?" }
を渡すとリンククリック時に確認のダイアログが表示される -
redirect_to request.referrer
と記載すると、一つ前のページにリダイレクトさせられる -
CarrierWaveを使った画像ファイルの取り扱い手順
- Gemfileに
carrierwave
を追加し、bundle install -
rails generate uploader Xxx
でアップローダーを作成 - モデルに
mount_uploader :picture, PictureUploader
を追加 - ビューにimage_tagを追加
<%= image_tag micropost.picture.url if micropost.picture? %>
- Gemfileに
<span class="picture">
<%= f.file_field :picture %>
</span>
- モデルに独自定義したバリデーションを追加する場合は、
validates
ではなくvalidate
を使用する
感想
- 終盤のコンテンツだけあってなかなか内容が盛りだくさんだった。
- リスト13.50で空の配列(@feed_items = [])を追加している箇所は、
_feed.html.erb
の方を以下のように変えた方がわかりやすい気がした。
<% if @feed_items && @feed_items.any? %>
-
ただ、これだと空の配列追加と同様、フィードの一覧が表示されないので、普通に
redirect_to root_url
でHomeにリダイレクトすればよいのではと思ってやってみたが、リダイレクトするとflashメッセージが表示されずエラーが発生したことがわからない。やはりrender 'static_pages/home'
は必要なよう。 -
uploader導入後のローカルテストがredになり以下のERRORが表示された。
- NameError: uninitialized constant Micropost::PictureUploader
app/models/micropost.rb:4:in<class:Micropost>' app/models/micropost.rb:1:in
'
- NameError: uninitialized constant Micropost::PictureUploader
-
サーバーを再起動しても解消せず原因が分からなかったが、一度VSCodeのすべてのターミナルを閉じてから再度開き直して実行したところgreenになった。
-
herokuにpushした際、以下のエラーが発生した。
remote: !
remote: ! Failed to install gems via Bundler.
remote: !
(省略)
To https://git.heroku.com/xxx.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/xxx.git'
- herokuはpushされた際にbundle installも実行するようで、そこでこけるとpushがエラーになる模様(たしかにここまで一度もherokuでbundle installをしなかったが、勝手にやってくれていたらしい)
- bundle installがこけた原因は
heroku config:set
でAWSクレデンシャルを環境変数に設定していなかったことが原因のようで設定してからpushすると正常に動作した。