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