moxt

Just another Blog site

意識低いRuby on Rails再入門5

      2015/07/03

http://railstutorial.jp/chapters/sign-in-sign-out?version=4.0#top

この辺を読んだメモ。

Controllerに書かれたモデル系のロジックをHelperに切り出す

Controllerに書くのがなぜ悪いのだろう。。
と、はじめは思う。

正直『その追加する処理が1行程度なんだけど。。』とかであれば、Controllerにはモデル系のロジックを書いてはいけない!!!と、神経質にならずに書いちゃっても良いと思う。

ただ、その追加する処理があらゆるControllerで使われるとか、行数が複数行になりそうといった場合はモデルの中に押し込むか、HelperやDecoratorに押し込めないか検討する。

仮にモデルやHelperに処理Aを押し込んでおくと、その処理Aが変更になったとしても処理Aの中身を変えれば処理Aを参照してる箇所全てに変更が反映される。
処理AをいろんなControllerにベタ書きすると、処理Aを変更するときにあらゆるControllerを書き直す必要がある。
書き換え作業が面倒だし、あるControllerで書き換えをミスったためにバグが出てしまった、なんてことが想像できる。
共通する処理はどこかに集約することで変更に強くなる。
一方で、集約しすぎると複数人が1つのクラスを同時に編集することが起きる。
すると、gitなどを使ってる場合コンフリクトが発生することが想像できる。
この辺のバランスやテクニックについてまだまだ自分の中で確立できてないので学びの余地がある。

それから単純にControllerの中で処理がベタ書きされているとコードの見通しが悪くなる。
Controllerの外に追い出せるなら追い出したいし、それが難しそうであれば処理をメソッド化してベタ書きされた『どうやるか』コードを、メソッドの呼び出しに変更して『なにをしているか』に変えてゆくと見やすくなる。

前回SessionsControllerというログイン系を管理するControllerを書いた。こんな感じ。

このsign_inをhelperに委譲する。
SessionsHelperにsign_inというメソッドを追加する

Controllerに書いてた処理をSessionsHelperにコピペしただけ。

これでログイン処理をControllerから分離できた。

ログイン状態であるか確認したい

ログインの処理はできた。
何度か触れているが、ウェブアプリを作っているとログインが必須な画面やアクションと遭遇する。
それらを対応するたびにログイン画面を表示させられて、必要な情報を入力することをユーザ側は煩わしいと思う。
なので、セッションという手形情報を追加した。

ログイン状態が必須な画面・アクションではセッションの状態を確認する処理が必要になる、ということが分かると思う。
そうするとログイン状態が必要な何かしらのControllerの中でCookieのremember_tokenを引っ張ってきて、

こんな感じの照合作業を行う必要がある。

ログインが必要な様々な画面で↑のような処理を書くのは煩雑だろう。

この辺りの処理をSessionsHelperに任せられないだろうか。

def sign_in?
User.find_by(remember_token: cookies[:remember_token]).nil?
end

こんな感じ。

これで、sign_in?をController内で呼べるようになった。
ログイン状態の確認が必要なControllerにinclude SessionsHelperと書けばsign_in?を呼び出せる。

いちいちControllerにinclude SessionsHelperを書くのも面倒だ、という場合は

  • ApplicationControllerでinclude
  • LoginRequiredControllerみたいなモノを作って、その中にSessionsHelperをincludeしログインが必要なControllerはLoginRequiredControllerを継承するようにする

などなど、楽にするやり方はいろいろあると思うのでやってみるとよい。

メモ化を使ってログイン状態の確認を少し効率化する

先ほどSessionsHelperに追加したsign_in?メソッドは毎回find_byを呼び出している。
特にキャッシュしていない限りは毎度DBにアクセスしている、ということだ。

  • ログイン状態であるか確認する
  • ログイン状態であればユーザの名前を表示する

このような2つの処理をController内で行うと、Userを探す処理を2回実行することになる。
一度取得したUserを使い回すと効率は良さそうだ。

『メモ化』という方法を使うと良いらしい。

SessionsHelperに次のようなメソッドを追加する。

current_userを呼ぶと@current_userの値が返ってくる。
@current_userはSessionsHelperのインスタンス変数ではなく、includeしているControllerのインスタンス変数、という扱いになる。

このcurrent_userをつかってsign_in?を次のように書き換える。

参考元だと要素代入を利用したコードになってる。

 - プログラミング

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

  関連記事

no image
Toolbarで表示する矢印アイコンの色を変えたい

http://stackoverflow.com/questions/26788464/how-to-change-color-of-the-back-arrow-in-the-new-material-theme 動的に色を変えるイイカンジな方法が分からず困っていた。 …

no image
Macでdocker系のコマンドが使えなくなったら確認すること

OSXではdockerは使えないため、別にVMを立ち上げ、そこでdockerを動かしてる。 macからdockerコマンドを使うためにboot2dockerというコマンドを使う。 …

no image
GrowthPushのAndroid-SDK(?)のコードを読んでみる

できること、できないことを知るために。 GrowthPush.java …

no image
意識低いRuby on Rails再入門2

Modelを作り、コンソール上からデータを追加した。 次はこのデータをlocalhost:3000にアクセスしたときに表示させてみたい。 …

no image
AndroidのHandlerって何?

Handlerは何?と、Handlerを直視するとHandlerの存在意義というかなんというか文脈を捉えることが難しい。 なので、まずはAndroidがシングルスレッドである、という所からスタートしてHandlerに向かってゆく。 …

logo_og
ReactNativeでGiphyのデータを表示する

まずは下記をサクッとパクってみる。 当方、比較的AndroiderなのでAndroidで。 …

no image
YosemiteでRubyMineが起動できない

yosemiteからjavaが1.7系になってる。 一方、rubymineは1.6系を想定している。 …

no image
意識低いRuby on Rails再入門1

整理がてらメモ。 Contents1 …

large_v
Docker Machineのメモ

随時追記する Contents1 …

no image
単語の出現頻度をlinuxコマンドだけで調べたい

無駄にpythonとか使おうとしてた。。 楽にできて良かった。 …