techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Rails Tutorial 5 Following users

Rails Tutorial 5 Following users

最終章。
他のユーザーをフォローする機能を追加する。

The Relationship model

まずはデータモデルの構成から。

  • Relationship モデルの作成
    • マイグレーションの生成
    • 複合キーインデックスの追加
$ rails generate model Relationship follower_id:integer followed_id:integer
Running via Spring preloader in process 3273
      invoke  active_record
      create    db/migrate/20170705223145_create_relationships.rb
      create    app/models/relationship.rb
      invoke    test_unit
      create      test/models/relationship_test.rb
      create      test/fixtures/relationships.yml
$ rails db:migrate
== 20170705223145 CreateRelationships: migrating ==============================
-- create_table(:relationships)
   -> 0.0056s
-- add_index(:relationships, :follower_id)
   -> 0.0007s
-- add_index(:relationships, :followed_id)
   -> 0.0006s
-- add_index(:relationships, [:follower_id, :followed_id], {:unique=>true})
   -> 0.0022s
== 20170705223145 CreateRelationships: migrated (0.0094s) =====================

次に関連付けを行う。

これまでは has_many の引数で与えたシンボルからモデル名を見つけてくれていたが、今回はクラス名を明示的に指定する。
同様に、これまでは [クラス名]_id で外部キーの名前を見つけてくれていただ、外部キーの名前も明示的に指定する。

とのこと。(裏でそんなに色々やってくれてたんか、というのが全く理解できてなかったことがここで露呈

続いて Relationship のバリデーションを追加する。

テストを作成してからバリデーションを作成し、テストが通ることを確認するが、

Exercises

にもある通り、Rails 5 からはバリデーションの追加が必須ではなくなったそうな。

optionalが出てきた から、これを使わない限りは存在性は保証されている、か。

following と followers の実装に進む。

  • has_many, through を使う
  • source を使ってどの id の集合であるかを明示的に指定
  • follow, unfollow メソッドの実装
    • テストの実装
    • メソッドの実装
    • テストが通ることの確認

これで任意のユーザーがフォローしているユーザーの追加、削除などができるようになる。

次に任意のユーザーをフォローしているユーザーを操作できるよう実装していく。 と言っても先の内容とほぼ同等。

A web interface for following users

GUI を実装して先ほどのメソッドを実際に動かしてみる。

  • seed を使ったサンプルデータの作成
  • フォローしているユーザー数、フォロワーのユーザー数を表示するパーシャルの作成
    • ルーティングの実装
      • member ルーティングオプションの使用
    • フォロー数、フォロワー数は count を使うと Rails が高速化の為に DB 内で合計した数値を返してくれる
    • Ajax から使えるように一部要素には CSS id を振っておく
    • SCSS の追加
  • Follow, Unfollow ボタンようパーシャルの作成
  • これらのパーシャルの表示をプロフィールページに追加

と進める。
ここまでで、フォローボタンの動作と、プロフィールページにフォローしているユーザーの数とフォロワー数が表示できるようになる。

次にフォローしているユーザーの一覧、フォロワーの一覧を表示するページを作成する。

  • ログイン済みユーザーにしか閲覧できないようにする
    • テストを先に実装
    • Users コントローラに following, followers アクションを追加
      • render を使って出力するビューを明示
    • following, followers 表示用の共通のビューを作成
  • 統合テストの作成
    • HTML の構造を網羅的に確認するテストは壊れやすいので簡易な確認にしておく
    • 空にしておいた Relationship の fixture を埋めてユーザー間のフォロー関係を作成する
    • 数が正しいか と URL が正しいかの2点を確認する
  • テストが全て通ることを確認する

Follow ボタンの基本的な動作を実装する。

  • Relationships コントローラの作成
  • アクセスコントロール
    • テストの実装
      • Follow ボタンはログイン済みユーザーにのみ使えるように
      • ログイン済みユーザーでない場合はログインページにリダイレクトされていることを確認
    • before フィルターの実装
  • create, destroy アクションの実装
    • フォーム送信されたパラメータから対象ユーザーを探す
    • follow, unfollow メソッドを実行する
    • 同じページを再読み込みする

これで動作するようになるが、最後の再読み込みが無駄なので無くしたい。ということで次の Ajax 編に突入する。

  • フォームを書き換える
    • remote: true を form_for に指定する
  • Relationships コントローラを書き換える
    • リクエストの種類に応じて応答を場合分けする
      • respond_to を使用する
  • RJS ファイルの作成
    • アクション名と同じファイル名で作成
    • フォームを follow用、unfollow用で書き換える
    • 表示する統計数を更新する
  • テストを作成する
    • Ajax のテストでは xhr :true を使用する
    • フォローしているユーザー数、フォロワー数が1ずつ増減することを確認する

The status feed

自分のマイクロポストと、自分がフォローしているユーザーのマイクロポストをフィードに表示する。

  • 振る舞いはわかりやすいので User モデルのテストから実装
    • フォローしているユーザーのマイクロポストがあることの確認
    • 自分自身のマイクロポストがあることの確認
    • フォローしていないユーザのマイクロポストが無いことの確認
  • とりあえずの実装
    • フォローしているすべてのユーザーを DB から取り出す
    • 上記を使ってフォローしているユーザーの配列を DB から取り出す

動くようにはなるが、ユーザー数が増えてくるとレスポンスが低下する問題があるのでサブセレクトを用いて作り変える。

DB から Ruby コード内に持ってくる回数を極力減らし、DB 内での操作のみに閉じることで高速化することができる、という理屈だが、この辺りは実際に何か作る際その時々に合わせて作りを考える必要がある。

Of course, even the subselect won’t scale forever. For bigger sites, you would probably need to generate the feed asynchronously using a background job, but such scaling subtleties are beyond the scope of this tutorial.

というわけで、非同期処理を使用するなどいろいろ頑張らないといけないケースも出てきたらがんばる。

その他

というわけで Rails Tutorial 終了。ありがとうございました。

ここからいろいろ作ってみよう& Rails 5.1 のキャッチアップをしようかな。