shell terminal
$ cd sample_app
$ rails s -b 0.0.0.0 -p 3000
Firefox: http://localhost:3000/
shell terminal
$ git checkout -b following-users
$ rails generate model Relationship follower_id:integer followed_id:integer
db/migrate/[timestamp]_create_relationships.rb
add_index :relationships, :follower_id
add_index :relationships, :followed_id
add_index :relationships, [:follower_id, :followed_id], unique: true
$ rails db:migrate
== 20170722215137 CreateRelationships: migrating ==============================
-- create_table(:relationships)
-> 0.0247s
-- add_index(:relationships, :follower_id)
-> 0.0011s
-- add_index(:relationships, :followed_id)
-> 0.0011s
-- add_index(:relationships, [:follower_id, :followed_id], {:unique=>true})
-> 0.0016s
== 20170722215137 CreateRelationships: migrated (0.0288s) =====================
app/models/user.rb
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
app/models/relationship.rb
class Relationship < ApplicationRecord
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
end
test/models/relationship_test.rb
require 'test_helper'
class RelationshipTest < ActiveSupport::TestCase
def setup
@relationship = Relationship.new(follower_id: users(:michael).id,
followed_id: users(:archer).id)
end
test "should be valid" do
assert @relationship.valid?
end
test "should require a follower_id" do
@relationship.follower_id = nil
assert_not @relationship.valid?
end
test "should require a followed_id" do
@relationship.followed_id = nil
assert_not @relationship.valid?
end
end
app/models/relationship.rb
validates :follower_id, presence: true
validates :followed_id, presence: true
test/fixtures/relationships.yml
# empty
app/models/user.rb
has_many :following, through: :active_relationships, source: :followed
test/models/user_test.rb
test "should follow and unfollow a user" do
michael = users(:michael)
archer = users(:archer)
assert_not michael.following?(archer)
michael.follow(archer)
assert michael.following?(archer)
michael.unfollow(archer)
assert_not michael.following?(archer)
end
app/models/user.rb
# Follows a user.
def follow(other_user)
following << other_user
end
# Unfollows a user.
def unfollow(other_user)
following.delete(other_user)
end
# Returns true if the current user is following the other user.
def following?(other_user)
following.include?(other_user)
end
app/models/user.rb
has_many :microposts, dependent: :destroy
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
test/models/user_test.rb
test "should follow and unfollow a user" do
assert archer.followers.include?(michael)
end
db/seeds.rb
# Microposts
users = User.order(:created_at).take(6)
50.times do
content = Faker::Lorem.sentence(5)
users.each { |user| user.microposts.create!(content: content) }
end
# Following relationships
users = User.all
user = users.first
following = users[2..50]
followers = users[3..40]
following.each { |followed| user.follow(followed) }
followers.each { |follower| follower.follow(user) }
shell terminal
$ rails db:migrate:reset
$ rails db:seed
config/routes.rb
Rails.application.routes.draw do
# get 'password_resets/new'
# get 'password_resets/edit'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
# post '/signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
member do
get :following, :followers
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :microposts, only: [:create, :destroy]
end
app/views/shared/_stats.html.erb
<% @user ||= current_user %>
<div class="stats">
<a href="<%= following_user_path(@user) %>">
<strong id="following" class="stat">
<%= @user.following.count %>
</strong>
following
</a>
<a href="<%= followers_user_path(@user) %>">
<strong id="followers" class="stat">
<%= @user.followers.count %>
</strong>
followers
</a>
</div>
app/views/static_pages/home.html.erb
<section class="stats">
<%= render 'shared/stats' %>
</section>
app/assets/stylesheets/custom.scss
.stats {
overflow: auto;
margin-top: 0;
padding: 0;
a {
float: left;
padding: 0 10px;
border-left: 1px solid $gray-lighter;
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;
}
a {
padding: 0;
}
}
.users.follow {
padding: 0;
}
Firefox: http://localhost:3000/
config/routes.rb
resources :relationships, only: [:create, :destroy]
app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
<section class="stats">
<%= render 'shared/stats' %>
</section>
</aside>
<div class="col-md-8">
<%= render 'follow_form' if logged_in? %>
<% if @user.microposts.any? %>
<h3>Microposts (<%= @user.microposts.count %>)</h3>
<ol class="microposts">
<%= render @microposts %>
</ol>
<%= will_paginate @microposts %>
<% end %>
</div>
</div>
Firefox: http://localhost:3000/users/2
Firefox: http://localhost:3000/users/6
test/controllers/users_controller_test.rb
test "should redirect following when not logged in" do
get following_user_path(@user)
assert_redirected_to login_url
end
test "should redirect followers when not logged in" do
get followers_user_path(@user)
assert_redirected_to login_url
end
app/controllers/users_controller.rb
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
def following
@title = "Following"
@user = User.find(params[:id])
@users = @user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
@title = "Followers"
@user = User.find(params[:id])
@users = @user.followers.paginate(page: params[:page])
render 'show_follow'
end
Firefox: http://localhost:3000/users/1/following
Firefox: http://localhost:3000/users/1/followers
Thanks for sharing this blog post,Nice written skill selenium Online Course Bangalore
ReplyDelete