心はいつもAirPucci (空元気でもいいから)

毎日がPucciを着ているような気分

RailsTutorial4.0を高速で復習する。11.2章。

   


11.2フォローしているユーザー用のWebインターフェイス、です。
モデルができたので、viewとcomtorollerを作ります。

11.2.1フォローしているユーザーのサンプルデータ、です。

テストデータづくり

リスト11.17 フォローしている、またはフォローされている関係を表すリレーションシップをサンプルデータに追加する。
lib/tasks/sample_data.rake

namespace :db do
  desc "Fill database with sample data"
  task populate: :environment do
    make_users
    make_microposts
    make_relationships
  end
end

def make_users
  admin = User.create!(name:     "Example User",
                       email:    "example@railstutorial.jp",
                       password: "foobar",
                       password_confirmation: "foobar",
                       admin: true)
  99.times do |n|
    name  = Faker::Name.name
    email = "example-#{n+1}@railstutorial.jp"
    password  = "password"
    User.create!(name:     name,
                 email:    email,
                 password: password,
                 password_confirmation: password)
  end
end

def make_microposts
  users = User.all(limit: 6)
  50.times do
    content = Faker::Lorem.sentence(5)
    users.each { |user| user.microposts.create!(content: content) }
  end
end

def make_relationships
  users = User.all
  user  = users.first
  followed_users = users[2..50]
  followers      = users[3..40]
  followed_users.each { |followed| user.follow!(followed) }
  followers.each      { |follower| follower.follow!(user) }
end
bundle exec rake db:reset
bundle exec rake db:populate
bundle exec rake test:prepare

11.2.2統計とフォロー用フォーム、です。

統計情報というと大げさです。ようは、フォロー数とフォロワー数を表示します。

ルートづくり

HTTPリクエスト URL アクション 名前付きルート
GET /users/1/following following following_user_path(1)
GET /users/1/followers followers followers_user_path(1)
表11.1リスト11.18のリソースのカスタムルールで提供されるRESTfulなルート

resourcesブロックの内側で:memberメソッドを使用しています。これは初登場ですので、どんな動作をするのか推測してみてください。 (注: リスト11.18のコードは resources :usersを置き換えます)

リスト11.18 followingおよびfollowersアクションをUsersコントローラに追加する。
config/routes.rb

SampleApp::Application.routes.draw do
  resources :users do
    member do
      get :following, :followers
    end
  end
略
end

Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
following_user GET /users/:id/following(.:format) users#following
followers_user GET /users/:id/followers(.:format) users#followers
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
signup GET /signup(.:format) users#new
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
signin GET /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
microposts POST /microposts(.:format) microposts#create
micropost DELETE /microposts/:id(.:format) microposts#destroy
こうなりました。

テストを書く

リスト11.19 Homeページ上の、フォローしているユーザー/フォロワーの統計情報をテストする。
spec/requests/static_pages_spec.rb

require 'spec_helper'

describe "Static pages" do
略
  describe "Home page" do
略
    describe "for signed-in users" do
      let(:user) { FactoryGirl.create(:user) }
      before do
        FactoryGirl.create(:micropost, user: user, content: "Lorem")
        FactoryGirl.create(:micropost, user: user, content: "Ipsum")
        sign_in user
        visit root_path
      end

      it "should render the user's feed" do
        user.feed.each do |item|
          expect(page).to have_selector("li##{item.id}", text: item.content)
        end
      end

      describe "follower/following counts" do
        let(:other_user) { FactoryGirl.create(:user) }
        before do
          other_user.follow!(user)
          visit root_path
        end

        it { should have_link("0 following", href: following_user_path(user)) }
        it { should have_link("1 followers", href: followers_user_path(user)) }
      end
    end
  end
略
end

実装する

リスト11.20 フォローしているユーザーとフォロワーの統計情報を表示するパーシャル。
app/views/shared/_stats.html.erb

<% @user ||= current_user %>
<div class="stats">
  <a href="<%= following_user_path(@user) %>">
    <strong id="following" class="stat">
      <%= @user.followed_users.count %>
    </strong>
    following
  </a>
  <a href="<%= followers_user_path(@user) %>">
    <strong id="followers" class="stat">
      <%= @user.followers.count %>
    </strong>
    followers
  </a>
</div>

リスト11.21 フォロワーの統計情報をHomeページに追加する。
app/views/static_pages/home.html.erb

<% if signed_in? %>
略
      <section>
        <%= render 'shared/user_info' %>
      </section>
      <section>
        <%= render 'shared/stats' %>
      </section>
      <section>
        <%= render 'shared/micropost_form' %>
      </section>
略
<% else %>
略
<% end %>

テストはパスします。

リスト11.22 Homeページのサイドバー用SCSS。
app/assets/stylesheets/custom.css.scss

略
/* sidebar */
略
.stats {
  overflow: auto;
  a {
    float: left;
    padding: 0 10px;
    border-left: 1px solid $grayLighter;
    color: gray;
    &:first-child {
      padding-left: 0;
      border: 0;
    }
    &:hover {
      text-decoration: none;
      color: $blue;
    }
  }
  strong {
    display: block;
  }
}

.user_avatars {
  overflow: auto;
  margin-top: 10px;
  .gravatar {
    margin: 1px 1px;
  }
}
略

フォロー、解除の作り込み

リスト11.23 フォロー/フォロー解除ボタン用のパーシャル。
app/views/users/_follow_form.html.erb

<% unless current_user?(@user) %>
  <div id="follow_form">
  <% if current_user.following?(@user) %>
    <%= render 'unfollow' %>
  <% else %>
    <%= render 'follow' %>
  <% end %>
  </div>
<% end %>

リスト11.24 ユーザーのリレーションシップ用のルートを追加する。
config/routes.rb

SampleApp::Application.routes.draw do
略
  resources :sessions,      only: [:new, :create, :destroy]
  resources :microposts,    only: [:create, :destroy]
  resources :relationships, only: [:create, :destroy]
略
end

リスト11.25 ユーザーをフォローするフォーム。
app/views/users/_follow.html.erb

<%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %>
  <div><%= f.hidden_field :followed_id %></div>
  <%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>

リスト11.26 ユーザーをフォロー解除するフォーム。
app/views/users/_unfollow.html.erb

<%= form_for(current_user.relationships.find_by(followed_id: @user),
             html: { method: :delete }) do |f| %>
  <%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>

リスト11.27 ユーザープロファイルページにフォロー用のフォームとフォロワーの統計情報を追加する。
app/views/users/show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="span4">
    <section>
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
    <section>
      <%= render 'shared/stats' %>
    </section>
  </aside>
  <div class="span8">
    <%= render 'follow_form' if signed_in? %>
略
  </div>
</div>

いったんコミットしておきます。次は、
11.2.3「フォローしているユーザー」ページと「フォロワー」ページ
です。

 - テクニカル ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

パーフェクトRuby 1章Rubyの概要

メタプログラミングRubyもいいのですが、余計な物語仕立てがどうも性に合わず、消 …

Mac miniの液晶モニターにDell U2713HM使っています。

次期モデルが出るかもしれないのにMac miniを買って、自分でメモリを16Gに …

no image
MacBookAir 1日め

ようやくMacBookAir を購入しました。Dellノートがずっと調子悪かった …

Macにコマンドラインツールをインストールする

Mac miniのメモリが16Mになったので、気分も新たに、Ruby on Ra …

Google Webfont使ってみたよ

地元に戻ってきてまず思ったのは「観光サイトを立ち上げたい」ということ。いや、観光 …

iPhoneアプリ開発のお勉強方法です。

Objective-C苦節3ヶ月アプリ作れるようになったと書きましたが、本日アプ …

RailsTutorial4.0を高速で復習する。8章。

仕様の探求 userモデルには、登録と認証、承認に必要なモデルは既に作ってありま …

パーフェクトRuby 2章Rubyの基礎 2-3 条件分岐と真偽値

p50 2-3 条件分岐と真偽値 falseとnil以外は全部true p51 …

no image
RailsTutorial4.0を高速で復習する。5.3.4章。

5.3.4RSpecを洗練させる、です。 確かに、名前付きルートに書き換えていて …

no image
RailsTutorial4.0を高速で復習する。3.2章。

3.2章は最初のテストです。 Railsチュートリアルは、アプリケーションの振る …