さんさろ

さんさろ

プロダクトエンジニアの雑記&技術、たまにドイツ

Ruby on Rails5 のレッスンに突入 その3(完)

Ruby on Rails5

さて、昨日はRuby on Rails5 レッスンでのログイン回りや認可を実装しました。

binthec.hatenablog.com 

使う学習サイトは同じく Progate です。今日で Ruby on Rails5 のレッスンを終わらせる予定です。

 

履修してるレッスン

  • Ruby on Rails5
  • 目標:TweetApp(TwiiterみたいなSNS)を作ること

昨日は「Ruby on Rails5」のレッスン8と道場3まで進みました。

今日はレッスン9から最後まで進めていきます。DBのリレーションなどをやるようですね。

  

リレーション…?(1対多)

  • リレーションをするのかと思いきや、やっぱりこっちも自作。あるぇ…?ORMがもしかして、ない…?流石にそれはないか?まだやらないだけ、かな……?
  • Post モデルの中で投稿ユーザの情報を返すインスタンスメソッドを定義する
    class Post < ApplicationRecord
        ...
        def user
            return User.find_by(id: self.user_id)
        end
    end
  • 呼び出し側は、post から user を呼び出せる
     def show
        @post = Post.find_by(id: params[:id])
        @user = @post.user
    end
  • 逆に、user に紐づく posts を引く時には Userモデルに posts メソッドを定義する
    class User < ApplicationRecord
        ...
        def posts
            return Post.where(user_id: self.id)
        end
    end
  • 使う時は@user に対して posts メソッドを呼び出す
    <% @user.posts.each do |post| %>
  • flash[:notice] に〜を代入してください、の時に"" ダブルクオートが付いてたり付いてなかったりするのは、これは注意力を付けるためにわざとやってるんだろうか…。

 

リレーション…?(多対多)

  • 中間テーブルに該当の値があるかどうか見る
    <% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
        いいね!済み
    <% else %>
        <%= link_to("いいね!", "/likes/#{@post.id}/create", {method: "post"}) %>
    <% end %>
    …そんまんまですね。(そしてまたここで {method: "post"} になってる)
    find_by は何もない場合の戻り値が nil なので判定に使える、ということらしい。
  • ajaxを使うのかと思ったらそんな事はなかった。流石にないか。

 

モデル

  • destroy メソッド。以前も出てきたけど復習も兼ねて。
    @like.destroy
    ソフトデリートってあるのかなぁ。
  • where メソッドとcount メソッド
    @likes_count = Like.where(post_id: params[:id]).count

 

  • link_toメソッドをHTMLに対して使う場合には少し異なった書き方をする
  • 文字列に対して
    <%= link_to("リンクテキスト", "/posts/index") %>
  • HTMLに対して
    <%= link_to("/likes/#{@post.id}/create", {method: "post"}) do %>
         <span class="fa fa-heart like-btn"></span>
    <% end %>

 

 gem(ジェム)

  • gemとは
    RubyRailsでプログラミングをする際に「よく使う機能」をパッケージ化したものです。Railsにインストールすることで使用することができます。
  • ほおほお。Composerのようなものか。CentOS上でコマンドを見たことだけはある。
  • Gemfile :インストールしたいgemを記述するファイル
    へえー。composer.json みたいなものか。
    gem 'rails', '5.0.3'
    gem 'bcrypt'
    バージョン名を省略すると、最新版をインストールする
  • Gemfile.lock :自動生成されるファイル。composer.lock みたいなもんですね、きっと。
  • gem インストール実行
    $ bundle install

 

bcrypt パッケージ

  • has_sercure_password メソッドというメソッドが使えるので、モデルに設定する。use も何もいらないらしい。また、has_secure_password は presence (存在するかどうか)のバリデーションも一緒に行う。
    class User < ApplicationRecord
       has_sercure_password
       ...
  • 項目名が password の中身を、save 時にbcrypt を通して「password_digest」カラムに入れてくれるので、項目名は password のままでよい
  • ログインさせるには、そのメールアドレスを持つユーザが存在し、かつ、bcrypt の authenticate メソッドを使ってパスワードが一致するかを確認して、通す
    @user = User.find_by(email: params[:email])
    if @user && @user.authenticate(params[:password])
        session[:user_id] = @user.id
        ....
    else
        ....
    end

  

余談:気がついた事

CakePHPRuby on Railsでは、バリデーションはモデルに記述し、モデルのsaveメソッドが走る時に行われる。

Laravel では、バリデーションは基本自分で設定するのでモデルに書いてもコントローラに書いても良くて、いつのタイミングでも掛けられる。私は大体、フォームからデータが渡ってきたタイミングでバリデーション掛けていたので、今回ちょっと違和感があって気が付きました。

どっちがいいんでしょうね。

私はLaravelでも良くモデルにバリデーションを配列で返すメソッド作ってたので、結局やってることは変わらない気がしますけども。save メソッドで呼び出された際にバリデーション通すか、その前に通すかの違いですかね。

でもCakePHPでは特定の項目だけ特定の場合にバリデーション掛けたくないシチュエーションがあった時に、ちょっと別オプション指定してあげたりが面倒だったので、Laravel の方が自分でタイミングと項目を設定出来る分、融通が効くと言えなくもないけど、結局全部手動だからなぁ。

一長一短ですかね。

 

Ruby on Rails5 のレッスンを修了!

レッスン6〜8と、道場3の合わせて4つを修了し、Ruby on Rails5 のレッスン全てが終わりました。ここまで3時間強でした。

さすがにパスワードの暗号化は出てきましたね。

DBのリレーションを張るのかと思いきや、ORMでなく手動だったのは少し驚きました。レッスンに入り切らなかったんですかね。どっちにしてもORMはいずれ格闘しなきゃいけないと思いますので、概念だけおさらいするという意味でいい復習になりました。

デバッグの仕方くらい教えてくれたら嬉しかったなーと思いましたが、別にそんくらい調べればすぐ分かることなので、あとは自分でなんとかしましょうってことですね。

次はローカル環境作って、公式ドキュメント見ながらORMとかソフトデリートとか探しつつ色々試してみようかと思います。とりあえず Multiauth やらねば。

正月休み中しっかり勉強したし、明日は1日遊んで、明後日からまた仕事ですね。正月明け早々に出張です……。

 

兎にも角にも、Ruby on Rails5 のレッスンは無事修了〜。

Progate さんありがとうございました。

折角だからjQueryPythonもやるだけやってみようかな。