196の日記

セキュリティ系の勉強、その他開発メモとか雑談、忘れそうな計算式などを書き溜める場所になっています. githhubはUnity触っていた頃ものがメイン https://github.com/196kakinuma [twitter https://twitter.com/196Ikuchil]

ruby チュートリアル 13章 メモ

belongs_to

指定したモデルと1対1の関係を持つ。参照元テーブルから参照先テーブルにアクセスする。モデル生成時にuser:referencesをつけるとモデル内に自動生成される。

#app/models/micropost.rb
class Micropost < ApplicationRecord
   belongs_to :user
end

user:references

上の通りコマンドでモデル生成時にuser:referencesをつけると、自動的にインデックスと外部参照キー付きのuser_idカラムが追加される。

  def change
    create_table :microposts do |t|
      t.references :user, foreign_key: true #ここ
      t.timestamps
    end
  end

複合キーインデックス (Multiple Key Index)

複数の条件で並び替えができるようにする。下の時は、user_idに関連付けられたすべてのマイクロポストを作成時刻の逆順で取り出しやすくなる。注意としては、2つ目以降にしてしたカラムのみでインデックスは使用できない。あくまでuser_idでのソート後にcreated_atでソートが可能。

    add_index :microposts, [:user_id, :created_at]


モデルのvalid?メソッド

モデル内でのvalidatesで弾かれてる値が入っている場合にfalseが返される。正確に言うと、valid?メソッドを使用した際に初めて保持されている値が評価され、booleanを返す。errors.messagesインスタンスメソッドを使用すると、発生したエラーにアクセスできる。

 test "content should be present" do
    @micropost.content = "   "
    assert_not @micropost.valid?
  end


デフォルトスコープ

dbから引っ張り出す際の条件(orderやwhere)をデフォルトで指定できる。が、ググると否定的な記事が多かった。ある時特別な条件で引っ張ってきたい時に、スコープを外すのが大変&見落としがちになるからだそう。チュートリアルではmicropostを新しい順に取得するために使用していた。

Dependent: destroy

下のように使用すると、Userを削除した際にUesrに紐づいていたMicropostも同時に削除される。こうすることで、db内にアクセス不可能なMicropostが残ってしまうのを防ぐことができる。

takeメソッド

チュートリアルでUserモデルから最初の6人を取得するために使用した。1~10のArrayから最初の6つをとるコードは下。

[5] pry(main)> (1..10).to_a.take(6)
=> [1, 2, 3, 4, 5, 6]


uninitialized constant ~Controller

この章に直接関係しないですが、RSpecでテスト書いている際に下のようなエラーが出ました。出現箇所としては、Controllerのテストで、createや`destroy``アクションを読んだ時でした。

ActionController::RoutingError:
        uninitialized constant MicropostController


根本原因としては、config/route.rbのルーティングミス。

#間違い
resources :micropost,           only:[:create,:destroy]
#正しい
resources :microposts,           only:[:create,:destroy]


単数形のままだと、確かにcreateのパス取得にmicropost_index_pathとか言う謎文字列を使わされました。正しく設定ができていれば、createアクションはmicroposts_pathで取得することができます。

current_userヘルパー

app/controllers/microposts_controller.rbで以前作成したcurrent_userヘルパーが再び使用されるが、これは定義元のSessionsHelperが大元のApplicationControllerincludeされているため、どこでも使える。
注意として、決してユーザ情報が保持されたインスタンス変数がコントローラ間で共有されているわけではなく、ヘルパーを介してセッションとクッキーを調べ、その情報を利用してユーザ情報についてコントロールしている。なので、共有しているように見えているのは、ヘルパーの実装がそうやって扱えるようにされているから。

SQLクエリのエスケープ

?記号で実現する。具体的には下参照。しかし、ググってみてもあまりこのやり方はヒットしないので、今後チュートリアルで別のやり方が登場するかも..?

 Micropost.where("user_id = ?", id)


request.referrer

リクエストが発行されたページのURLを返してくれる。フレンドフォワーディングではrequest.urlを使用して飛ぼうとしていた先のURLを拾っていた。注意として、nilを返してくる場合もあるので、||でデフォルトのジャンプ先を指定してあげておくと良い。

redirect_to request.referrer || root_url


Rails5の新機能としてredirect_back(fallback_location: root_url)と書くと上のコードと同じ動きをしてくれる。

テストでwill_paginateが表示されない

この賞に限ったことではないが、テストでdiv.paginationに一致する部分を探しても見つからないことがあった。ブラウザ上では確認済みだったので原因探しに困った。結果として、ページネートするコンテンツが1つしか生成されていなかったのが原因。テスト時のページ表示前にダミーデータをたくさん作ってあげることで解決する。(1ページのデフォルト値よりも多く)

CarrierWave

画像アップローダのgem

Mini_Magick

画像のリサイズができるようになるGem. ただ、ImageMagickを使用することになるので、脆弱性とか心配? MiniMagick自身の役割としては、本体にインストールしたImageMagickRubyの橋渡しになってくれるGem ImageMagickは様々な画像に対応できているがゆえにガバガバになっているイメージがあるので、載せられる画像のフォーマットを制限する。チュートリアルではCarrierWaveを利用している。

MIMEタイプ

データのタイプを指定したりする。元々は、テキストしか扱えない電子メールで様々なフォーマットのデータを扱えるようにするために使用されている。チュートリアルでは画像の拡張子をクライアント側で限定するために使用。