diff --git a/app/assets/javascripts/relationships.coffee b/app/assets/javascripts/relationships.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/relationships.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss index b2a993a..3e57548 100644 --- a/app/assets/stylesheets/custom.scss +++ b/app/assets/stylesheets/custom.scss @@ -147,6 +147,45 @@ aside { .gravatar_edit { margin-top: 15px; } +.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; + } + a { + padding: 0; + } +} + +.users{ + .follow { + padding: 0; + } +} input, textarea, select, .uneditable-input { border: 1px solid $colour6; diff --git a/app/assets/stylesheets/relationships.scss b/app/assets/stylesheets/relationships.scss new file mode 100644 index 0000000..ca5c640 --- /dev/null +++ b/app/assets/stylesheets/relationships.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Relationships controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/relationships_controller.rb b/app/controllers/relationships_controller.rb new file mode 100644 index 0000000..c5c4f9c --- /dev/null +++ b/app/controllers/relationships_controller.rb @@ -0,0 +1,23 @@ +class RelationshipsController < ApplicationController + before_action :logged_in_user + + def create + user = User.find_by id: params[:followed_id] + current_user.follow user + respond_to do |format| + format.html { redirect_to @user } + format.js + end + redirect_to user + end + + def destroy + user = Relationship.find_by(id: params[:id]).followed + current_user.unfollow user + respond_to do |format| + format.html { redirect_to @user } + format.js + end + redirect_to user + end +end diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index ee39a52..7a7eefd 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -2,7 +2,7 @@ class StaticPagesController < ApplicationController def home return unless logged_in? @micropost = current_user.microposts.build - @feed_items = current_user.microposts.micropost_desc.page(params[:page]).per Settings.page.per_page + @feed_items = current_user.feed.page(params[:page]).per Settings.page.per_page end def help diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 692caa8..95c4c60 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,12 +1,12 @@ class UsersController < ApplicationController - before_action :find_user, only: [:show, :edit, :update] + before_action :find_user, only: [:show, :edit, :update, :following] before_action :logged_in_user, only: [:index, :edit, :update, :show, :destroy] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: :destroy def index @users = User.where(activated: true).page(params[:page]) - .per(Settings.page.per_page) + .per Settings.page.per_page end def new @@ -55,6 +55,16 @@ def destroy end end + def following + @users = @user.following.page(params[:page]) + render :show_follow + end + + def followers + @users = @user.followers.page(params[:page]) + render :show_follow + end + private def user_params @@ -69,10 +79,10 @@ def find_user end def logged_in_user - unless logged_in? - flash[:danger] = t "title2" - redirect_to login_url - end + unless logged_in? + flash[:danger] = t "title2" + redirect_to login_url + end end def correct_user @@ -84,4 +94,3 @@ def admin_user redirect_to root_url unless current_user.admin? end end - diff --git a/app/models/relationship.rb b/app/models/relationship.rb new file mode 100644 index 0000000..d362152 --- /dev/null +++ b/app/models/relationship.rb @@ -0,0 +1,4 @@ +class Relationship < ApplicationRecord + belongs_to :follower, class_name: User.name + belongs_to :followed, class_name: User.name +end diff --git a/app/models/user.rb b/app/models/user.rb index ce3301c..fb33701 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,22 +1,30 @@ class User < ApplicationRecord has_many :microposts, dependent: :destroy + has_many :active_relationships, class_name: Relationship.name, + foreign_key: "follower_id", + dependent: :destroy + has_many :passive_relationships, class_name: Relationship.name, + foreign_key: "followed_id", + dependent: :destroy + has_many :following, through: :active_relationships, source: :followed + has_many :followers, through: :passive_relationships, source: :follower attr_accessor :remember_token, :activation_token, :reset_token before_save :downcase_email before_create :create_activation_digest - validates :name, presence: true, length: { maximum: Settings.maximum.length_name } + validates :name, presence: true, length: {maximum: Settings.maximum.length_name} VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i - validates :email, presence: true, length: { maximum: Settings.maximum.length_email }, - format: { with: VALID_EMAIL_REGEX }, - uniqueness: { case_sensitive: false } + validates :email, presence: true, length: {maximum: Settings.maximum.length_email}, + format: {with: VALID_EMAIL_REGEX}, + uniqueness: {case_sensitive: false} has_secure_password - validates :password, presence: true, length: { minimum: Settings.minimum.length_pass } + validates :password, presence: true, length: {minimum: Settings.minimum.length_pass} class << self def digest string - cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : - BCrypt::Engine.cost - BCrypt::Password.create(string, cost: cost) + cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : + BCrypt::Engine.cost + BCrypt::Password.create(string, cost: cost) end def new_token @@ -31,7 +39,7 @@ def remember def authenticated? attribute, token digest = send "#{attribute}_digest" return false if digest.nil? - BCrypt::Password.new(digest).is_password? token + BCrypt::Password.new(digest).is_password? token end def forget @@ -46,7 +54,7 @@ def send_activation_email UserMailer.account_activation(self).deliver_now end - def create_reset_digest + def create_reset_digest self.reset_token = User.new_token update_attribute(:reset_digest, User.digest(reset_token)) update_attribute(:reset_sent_at, Time.zone.now) @@ -60,6 +68,25 @@ def password_reset_expired? reset_sent_at < Settings.expired_time end + def feed + following_ids = "SELECT followed_id FROM relationships + WHERE follower_id = :user_id" + Micropost.where("user_id IN (#{following_ids}) + OR user_id = :user_id", user_id: id) + end + + def follow other_user + following << other_user + end + + def unfollow other_user + following.delete other_user + end + + def following? other_user + following.include? other_user + end + private def downcase_email @@ -67,7 +94,7 @@ def downcase_email end def create_activation_digest - self.activation_token = User.new_token - self.activation_digest = User.digest activation_token - end + self.activation_token = User.new_token + self.activation_digest = User.digest activation_token + end end diff --git a/app/views/relationships/create.js.erb b/app/views/relationships/create.js.erb new file mode 100644 index 0000000..f4faf45 --- /dev/null +++ b/app/views/relationships/create.js.erb @@ -0,0 +1,2 @@ +$("#follow_form").html("<%= j render "users/unfollow" %>"); +$("#followers").html("<%= @user.followers.count %>" diff --git a/app/views/relationships/destroy.js.erb b/app/views/relationships/destroy.js.erb new file mode 100644 index 0000000..9a2277b --- /dev/null +++ b/app/views/relationships/destroy.js.erb @@ -0,0 +1,2 @@ +$("#follow_form").html("<%= j render "users/unfollow" %>"); +$("#followers").html("<%= @user.followers.count %>"); diff --git a/app/views/shared/_stats.html.erb b/app/views/shared/_stats.html.erb new file mode 100644 index 0000000..d60c3f4 --- /dev/null +++ b/app/views/shared/_stats.html.erb @@ -0,0 +1,15 @@ +<% @user ||= current_user %> +