一からRuby on Rails備忘録

Ruby on Rails Tutorial ステータスフィードを実装

「Ruby on Rails Tutorial」のサンプルアプリをAngularJSとBootstrap3を使う形にして作成します。最後に、ステータスフィードを実装します。
 
以前の仮作成の段階では、現在ログインしているユーザーのマイクロポストを取得して表示していました。
 
今回は、現在のユーザーにフォローされているユーザーのマイクロポストと合わせて表示するようにします。

1)Rails側のSQL設定
 
①前回のコード
 
$ vi app/models/user.rb

  def feed
    Micropost.where("user_id = ?", id)
  end

 
②Ruby on Railsチュートリアルのコード
 
$ vi app/models/user.rb

  def feed
    Micropost.from_users_followed_by(self)
  end

 
$ vi app/models/micropost.rb

  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
          user_id: user.id)
  end

 
③今回作成したコード
 
マイクロポスト一覧を表示する際、micropostsテーブルのカラム以外にユーザーID、ユーザー名、ユーザーのメールアドレスが必要です。
 
上記②のメソッドではユーザーIDは取得できますが、ユーザー名とメールアドレスはさらにusersテーブルをジョインして取得する必要があります。
 
直接コントローラ内からSQLを記述して、データを取得しました。
 
$ vi app/controllers/sessions_controller.rb

  def current_user
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    if current_user
      gravatar_id = Digest::MD5::hexdigest(current_user.email.downcase)
      conn = ActiveRecord::Base.connection
      sql = "SELECT microposts.*,users.name,users.email " +
            "FROM microposts,users " +
            "WHERE (user_id IN (" +
            "SELECT followed_id FROM relationships WHERE follower_id = " +
            current_user.id.to_s + " )" +
            "OR user_id = " + current_user.id.to_s + " ) " +
            "AND microposts.user_id = users.id"
      feed = conn.select_all(sql)
      @user_info = {
        user: current_user,
        gravatar_url: "https://secure.gravatar.com/avatar/#{gravatar_id}",
        microposts: current_user.microposts,
        feed: feed,
        followed_users: current_user.followed_users,
        followers:  current_user.followers
      }
      render json: @user_info, status: :accepted
    else
      head :no_content
    end
  end

 
2)AngularJSビューの設定
 
$ vi app/assets/templates/static_pages/home.html.erb

<h3>Micropost Feed</h3>
<ol class="microposts">
  <li ng-repeat="mp in currentitems">
    <a href="/users/{\{mp.user_id}}">
      <img alt="{\{mp.name}}"
           src="https://secure.gravatar.com/avatar/{\{hash(mp.email)}}?s=60"
           class="gravatar"
      />
    </a>
    <a href="/users/{\{mp.user_id}}">{\{mp.name}}</a>
    <div>{\{mp.content}}</div>
    <small class="text-muted">Posted {\{mp.created_at | date:'medium'}}</small>
  </li>
</ol>
モバイルバージョンを終了