さんさろ

さんさろ

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

Ruby on Rails5 のレッスンに突入 その2

Ruby on Rails5

さて、昨日はRuby on Rails5のレッスンに入っていきました。

binthec.hatenablog.com

引き続き今日はレッスンを進めて行きます。使う学習サイトは同じく Progate です。

 

 

あ、そういえば、明けましておめでとうございます。

 

履修してるレッスン

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

「Ruby on Rails5」のレッスン5と道場2まで進みました。今日はレッスン6からです。「Ruby on Rails5」のレッスン通してTwitterっぽいSNS作るということで、昨日まではルーティング、モデル、コントローラ、ビューの関係とか書き方を学びました。

レッスン6からはログイン機能を付けて行くようですね。

 

別にこの辺からはProgateでなくても良いような……とか思わなくもないですが笑 折角課金しましたので、このレッスン修了までは使ってみます。

 

ユーザ管理機能

  • 昨日も出てきましたが、復習も兼ねて。モデルとマイグレーション作成コマンドとマイグレートコマンド。やっぱりUserモデルのファイルが小文字なのがなんか気持ち悪い…
    $ rails g User name:string email:string
    $ rails db:migrate
  • Laravelみたいにコマンドで勝手にログイン機構を全部作ってくれたりは……しないのか。残念。
  • バリデーションのユニーク制約:
    validates :email, { uniqueness: true }
  • コントローラ名が複数形……でした、そう言えば。
  • ビューのnewとeditを一つにしたいな……
  • render()の引数はURIだと思ってたけど、ビューのパスだったっぽい。ユーザの新規作成画面のURIは /users/signup だけどrenderで指定する場合は
    render("users/new")
  • ページをめくるごとに設定していたname属性を消されて、知らずにブラウザで試して怒られるの巻\(^o^)/
  • お、もしかして編集の際のユニーク制約は、何もしなくても自分のID以外に検索をかけてくれてる?これは便利だ!何で判定してるんだろう。アクション名?
  • しかし、編集の際にDBのトランザクション張らなくていいんだろうか。また別のレッスンでやるのかな。

 

画像アップロード機能

  • 画像データはpublicディレクトリに保存
  • マイグレーションファイルの作成コマンド
    $ rails g migration add_image_to_users
  • マイグレーションファイルの書き方
    class AddImageNameToUsers < ActiveRecord::Migration[5.0]
        def change
            add_colums :users, :image_name, :string
        end
    end
  • HTMLヘルパーのようなものはないのかな…?
  • ファイル送信の際には、form_tagメソッドの第二引数に {multipart: true} 渡す。よく忘れるやつですね注意。
  • Ruby標準のFileクラスでファイルを書き込み出来る
    File.write("public/sample.txt""public/sample.txt""public/sample.txt""public/sample.txt", "Hello World")
    だと、sample.text に文字を書き込める。
    public ディレクトリに書き込む際もpublic から指定する必要がある事に注意。
  • 画像ファイル保存の場合には File.binwrite メソッドと、画像の read メソッドを使う
    @user.image_name = "#{@user.id}.jpg"
    image = params[:image]
    File.binwrite("public/images/#{@user.image_name}", image.read)
  • 画像表示の際には、

    <img src="<%= "/user_images/#{@user.image_name}" %>">

     ダブルクオートの中にダブルクオートを入れるのがなんか……不思議ですが。

 

ログイン機能

  • ログインのアクション命名規則URIは両方 /login
    ログイン画面(GET)   :login_form
    ログイン実行(POST):login
  • んんんwwパスワード平文入ってるんですけど、最初だからですよね??ww
  • form_tagメソッドはデフォルトでポストのルーティングを探す
    <%= form_tag("/login") do %>
    それにしても do をよく忘れてしまう…
  • Railsのログインはだいぶめんどくさいなぁ……ログイントレイトみたいなの欲しい……!
  • ログイン処理=「セッションの user_id キーにユーザIDを持たせること」
    session[:user_id] = @user.id
    変数名に入れるだけでセッションに入れてくれる機構があるんだな…
  • ログイン判定をして、ログイン中の場合に某かの値を出力
    <% if session[:user_id] %>
        ログイン中ユーザーのid: <%= session[:user_id] %>
    <% end %>
    うん、シンプルですね。これガードとかの判定出来るんかな。
  • ログアウトは逆にセッションのuser_idキーを空にするだけ。
    session[:user_id] = nil
    ……うん、シンプルですね。
  • 以前のレッスンでは link_to メソッドでポストのルーティングを指定する際には第3引数に
    {method: "post"}
    を指定してください、とあったのに、何の前置きもなく今度は
    {method: :post}
    を指定してください、になってたでござる……びっくりしたでござる。どっちでもいいみたいでござる。どっちでもいいよって書いてあったの私が見逃したかな…?
  • なるほど、連想配列…じゃなくてハッシュのキーを "key" ってのを :key に出来る、っていうだけの意味かと思ってたけど、これはもしかして "" ダブルクオートを : コロンで書くことが出来るってことだったのかな。なるほど、それで「省略して掛ける」って言ってたのか。ちょっと納得。
    だからPost.all.order(created_at: :desc) とかちょっと変な書き方だなあと思ったんですけど、そういうことだったのか……な……?え、今更?どんくさくてすみません……
  • 親クラスでメソッドとコントローラ呼び出し前に一括してメソッドを呼び出すことが出来る
    親クラス:application_controller
    class ApplicationController < ActionController::Base
       before_action :set_current_user
       #...
       def set_current_user
           @current_user = User.find_by(id: session[:user_id])
       end
    end
    と書けば、全てのControllerでアクション前にログイン中のユーザが取得出来る(=いちいち全てのControllerに書かなくて良い)。
    ビュー側では普通にcontrollerで指定したように
    <% if @current_user %>
        <%= link_to(@current_user.name, "/user/#{@current_user.id}/edit") %>
    <% end %>
    で利用出来る。
  • @変数は、
    @変数で定義した変数は同じクラスの異なるメソッド間で共通して使用することが可能です
  • なので、親クラスのapplication_controllerで先に
    before_action :set_current_user
    としておけば、application_controller 内の他のアクションでも @current_user が使えるよ、と。
  • 「ログイン済みしか見られない」ページを指定したい場合
    def authenticate_user
        if @current_user == nil
            flash[:notice] = "ログインが必要です"
            redirect_to("/login")
        end
    end
  • ログイン済みの場合に「見せないようにしたい」場合
    def forbid_login_user
        if @current_user
            flash[:notice] = "すでにログインしています"
            redirect_to("/posts/index")
        end
    end
  • で、各コントローラで、アクションの前に親クラスのメソッドを通す。このアクションでだけ通したい、という場合は only で指定出来る。
    before_action :authenticate_user, {only: [:index, :show]}
  • ログイン済みか否かでログイン画面表示さすかどうか、っての、全部自作かぁ……トレイトほしい。せめてミドルウェアほしい。

 

レッスンを4つ修了

レッスン6〜8と、道場3の合わせて4つを修了しました。ここまでで4時間半くらい。

昨日まではMVCの基本と表示部分の使い方などでそんなに難しい感じはありませんでしたが、ログイン回りは基本は変わりませんけどRailsっぽい書き方というか、今までとちょっと違ったので時間がかかりましたね。

Railsもコマンド叩けばログイン回り全部作ってくれればいいのに…!あとトレイトとミドルウェア欲しいです。ミドルウェアという概念は無いのかな…?あとで調べてみよう。

さすがに今日あと4つするの大変なので、今日はここまでにします。明日、Ruby on Rails5 のレッスンを最後まで行ければと。

ログイン回りを折角してるので、Multiauthもやってくれたら手間が省けて嬉しい。

 

Progateは本当に細かく丁寧に教えてくれるので、他のフレームワークしてる人には少し退屈かもしれませんが、初めてフレームワーク触る人にはとても優しい仕様になってますね。

 

ただ欲を言えば、レベルアップをお知らせしてくれるのは嬉しいけど、結構さくさくレベル上がってその度にいちいち閉じるボタン押すのが面倒なので、出来れば「もう表示しない」機能を付けてもらって、その場合は簡単なポップアップか何かだけでレベルアップを通知してくれると嬉しいなぁ…。

あと、エディタ画面でタブの入れ替え出来るとすごく嬉しい。

 

とりあえず、Ruby on Rails5 もあと少しでお終いですよー。