Skip to content
Permalink
Browse files

Add user following

  • Loading branch information
rcb09003 committed Nov 19, 2013
1 parent c9fa5d8 commit 4f2f61558d1698ca4baacd81213cd88fa7f1ecdf
@@ -139,6 +139,35 @@ aside {
}
}

.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;
}
}

#error_explanation {
color: #f00;
ul {
@@ -0,0 +1,21 @@
class RelationshipsController < ApplicationController
before_action :signed_in_user

def create
@user = User.find(params[:relationship][:followed_id])
current_user.follow!(@user)
respond_to do |format|
format.html { redirect_to @user }
format.js
end
end

def destroy
@user = Relationship.find(params[:id]).followed
current_user.unfollow!(@user)
respond_to do |format|
format.html { redirect_to @user }
format.js
end
end
end
@@ -1,5 +1,6 @@
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
before_action :signed_in_user,
only: [:index, :edit, :update, :destroy, :following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy

@@ -40,8 +41,26 @@ class UsersController < ApplicationController
render 'edit'
end
end

def following
@title = "Following"
@user = User.find(params[:id])
@users = @user.followed_users.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


private



def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
@@ -4,4 +4,13 @@ class Micropost < ActiveRecord::Base
default_scope -> { order('created_at DESC') }
validates :content, presence: true, length: { maximum: 140 }
validates :user_id, presence: true
end


# Returns microposts from the users being followed by the given user.
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
end
@@ -0,0 +1,6 @@
class Relationship < ActiveRecord::Base
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
@@ -1,5 +1,14 @@
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy

has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed

has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower

before_save { self.email = email.downcase }
before_create :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
@@ -19,8 +28,19 @@ class User < ActiveRecord::Base
end

def feed
# This is preliminary. See "Following users" for the full implementation.
Micropost.where("user_id = ?", id)
Micropost.from_users_followed_by(self)
end

def following?(other_user)
relationships.find_by(followed_id: other_user.id)
end

def follow!(other_user)
relationships.create!(followed_id: other_user.id)
end

def unfollow!(other_user)
relationships.find_by(followed_id: other_user.id).destroy!
end

private
@@ -29,3 +49,4 @@ class User < ActiveRecord::Base
self.remember_token = User.encrypt(User.new_remember_token)
end
end

@@ -0,0 +1,2 @@
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#followers").html('<%= @user.followers.count %>')
@@ -0,0 +1,2 @@
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>")
$("#followers").html('<%= @user.followers.count %>')
@@ -0,0 +1,15 @@
<% @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>
@@ -3,6 +3,9 @@
<aside class="span4">
<section>
<%= render 'shared/user_info' %>
</section>
<section>
<%= render 'shared/stats' %>
</section>
<section>
<%= render 'shared/micropost_form' %>
@@ -0,0 +1,5 @@
<%= form_for(current_user.relationships.build(followed_id: @user.id),
remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>
@@ -0,0 +1,9 @@
<% unless current_user?(@user) %>
<div id="follow_form">
<% if current_user.following?(@user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
@@ -0,0 +1,5 @@
<%= form_for(current_user.relationships.find_by(followed_id: @user),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
@@ -6,9 +6,15 @@
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
<section>
<%= render 'shared/stats' %>
</section>
</aside>

<div class="span8">
<%= render 'follow_form' if signed_in? %>

<% if @user.microposts.any? %>
<h3>Microposts (<%= @user.microposts.count %>)</h3>
<ol class="microposts">
@@ -0,0 +1,30 @@
<% provide(:title, @title) %>
<div class="row">
<aside class="span4">
<section>
<%= gravatar_for @user %>
<h1><%= @user.name %></h1>
<span><%= link_to "view my profile", @user %></span>
<span><b>Microposts:</b> <%= @user.microposts.count %></span>
</section>
<section>
<%= render 'shared/stats' %>
<% if @users.any? %>
<div class="user_avatars">
<% @users.each do |user| %>
<%= link_to gravatar_for(user, size: 30), user %>
<% end %>
</div>
<% end %>
</section>
</aside>
<div class="span8">
<h3><%= @title %></h3>
<% if @users.any? %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
<% end %>
</div>
</div>
@@ -1,8 +1,14 @@
SampleApp::Application.routes.draw do
resources :users do
member do
get :following, :followers
end
end
resources :products
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
@@ -0,0 +1,13 @@
class CreateRelationships < ActiveRecord::Migration
def change
create_table :relationships do |t|
t.integer :follower_id
t.integer :followed_id

t.timestamps
end
add_index :relationships, :follower_id
add_index :relationships, :followed_id
add_index :relationships, [:follower_id, :followed_id], unique: true
end
end
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20131107052554) do
ActiveRecord::Schema.define(version: 20131118215946) do

create_table "microposts", force: true do |t|
t.string "content"
@@ -29,6 +29,17 @@ ActiveRecord::Schema.define(version: 20131107052554) do
t.datetime "updated_at"
end

create_table "relationships", force: true do |t|
t.integer "follower_id"
t.integer "followed_id"
t.datetime "created_at"
t.datetime "updated_at"
end

add_index "relationships", ["followed_id"], name: "index_relationships_on_followed_id"
add_index "relationships", ["follower_id", "followed_id"], name: "index_relationships_on_follower_id_and_followed_id", unique: true
add_index "relationships", ["follower_id"], name: "index_relationships_on_follower_id"

create_table "users", force: true do |t|
t.string "name"
t.string "email"
@@ -1,26 +1,42 @@
namespace :db do

desc "Fill database with sample data"
task populate: :environment do

User.create!(name: "Example User",
email: "example@railstutorial.org",
password: "foobar",
password_confirmation: "foobar")
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}@railstutorial.org"
password = "password"
User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
end
users = User.all(limit: 6)
50.times do
content = Faker::Lorem.sentence(5)
users.each { |user| user.microposts.create!(content: content) }
end
end
make_users
make_microposts
make_relationships
end
end

def make_users
admin = User.create!(name: "Example User",
email: "example@railstutorial.org",
password: "foobar",
password_confirmation: "foobar",
admin: true)
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}@railstutorial.org"
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
@@ -0,0 +1,5 @@
require 'spec_helper'

describe Relationship do
pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit 4f2f615

Please sign in to comment.
You can’t perform that action at this time.