ぞえの技術めも

Ruby on Rails勉強中

【155日目】【1日20分のRailsチュートリアル】【第11章】お試しフィードを追加する

Ruby on Railsチュートリアル(第3版)

今日は「11.3.3 フィードの原型」から。

11.3.3 フィードの原型

マイクロポスト投稿フォームが動くようになりましたが、今の段階では投稿した内容をすぐに見ることができません。というのも、Homeページにまだマイクロポストを表示する部分が実装されていないからです。

ホーム画面でマイクロポスト投稿してからプロフィール画面に行けば見れるけど、めんどいよね!ってことか。そうだね、微妙に手間だね。

すべてのユーザーがフィードを持つので、feedメソッドはUserモデルで作るのが自然です。フィードの原型では、まずは現在ログインしているユーザーのマイクロポストをすべて取得してきます。(リスト11.44)

whereメソッドを使って現在ログインしているユーザーのマイクロポストを全て取得。

app/models/user.rb

  :
  # 試作feedの定義
  # 完全な実装は第12章「ユーザーをフォローする」を参照してください。
  def feed
    Micropost.where("user_id = ?", id)
  end
  :

上の疑問符があることで、SQLクエリにインクルードされる前にidが適切にエスケープされることを保証してくれるため、SQLインジェクションと呼ばれる深刻なセキュリティホールを避けることができます。

へー。SQLクエリ使うときは気をつけなきゃいけないのか。。。

サンプルアプリケーションでフィードを使うために、カレントユーザーのページ分割されたフィードに@feed_itemsインスタンス変数を追加し (リスト11.45)、次にフィード用のパーシャル (リスト11.46) をHomeページに追加します。

homeアクションに@feed_itemsインスタンス変数を追加。

app/controllers/static_pages_controller.rb

  def home
    if logged_in?
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
  end

フィード用のパーシャルはまずファイルを生成して

$ touch app/views/shared/_feed.html.erb

下記内容で更新。

app/views/shared/_feed.html.erb

<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

このとき、@feed_itemsの各要素がMicropostクラスを持っていたため、RailsはMicropostのパーシャルの呼び出すことができました。

Micropostクラスを持っていたら@feed_itemsで「1つのマイクロポストを表示するパーシャル」を呼び出すことができるんだ…!なんか不思議。

後は、いつものようにフィードパーシャルを表示すればHomeページにフィードを追加できます (リスト11.47)。

マイクロポストの投稿フォームタグの下にフィードを追加。

app/views/static_pages/home.html.erb

<% if logged_in? %>
    :
    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'shared/feed' %>
    </div>
    :

動作確認のためにサーバーを起動して

$ rails server -b $IP -p $PORT

ホーム画面にフィードが表示されました。

f:id:kt_zoe:20170623124901p:plain

マイクロポスト投稿もOK!

f:id:kt_zoe:20170623124925p:plain

ただしささいなことではありますが、マイクロポストの投稿が失敗すると、 Homeページは@feed_itemsインスタンス変数を期待しているため、現状では壊れてしまいます。

試しに空で投稿してみたらエラー画面が。。。

f:id:kt_zoe:20170623124950p:plain

最も簡単な解決方法は、リスト11.48のように空の配列を渡しておくことです。

とりあえずcreateアクションで空の配列渡すようにしておきましょう。

app/controllers/microposts_controller.rb

    :
    else
      @feed_items = []
      render 'static_pages/home'
    end
    :

これするとどうなるのかなー、と思ったらフィードが表示されなくなるのか。。。まぁ空の配列渡してるもんね。

f:id:kt_zoe:20170623125008p:plain

今日の学習時間は【28分】

次は「11.3.4 マイクロポストを削除する」から。