「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>