From 413bcf3540028179652194133d85df548ea4abfd Mon Sep 17 00:00:00 2001 From: TheNeedful-DO Date: Sat, 11 Nov 2023 11:34:52 +0000 Subject: [PATCH] Add basics of Follower feature --- app/models/profile.rb | 4 ++++ app/models/relationship.rb | 6 ++++++ app/models/user.rb | 21 +++++++++++++++++++ app/views/profiles/index.html.haml | 1 + app/views/profiles/show.html.haml | 2 ++ app/views/shared/_stats.html.haml | 10 +++++++++ app/views/users/show.html.erb | 4 ++++ config/routes.rb | 6 +++++- .../20231109015600_create_relationships.rb | 13 ++++++++++++ db/schema.rb | 12 ++++++++++- spec/factories/relationships.rb | 6 ++++++ spec/models/relationship_spec.rb | 5 +++++ 12 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 app/models/relationship.rb create mode 100644 app/views/shared/_stats.html.haml create mode 100644 db/migrate/20231109015600_create_relationships.rb create mode 100644 spec/factories/relationships.rb create mode 100644 spec/models/relationship_spec.rb diff --git a/app/models/profile.rb b/app/models/profile.rb index e23c028f..4c84113a 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -1,4 +1,8 @@ class Profile < ActiveRecord::Base belongs_to :user has_many :social_links + has_many :passive_relationships, class_name: "Relationship", + foreign_key: "followed_id", + dependent: :destroy + has_many :followers, through: :passive_relationships, source: :follower end diff --git a/app/models/relationship.rb b/app/models/relationship.rb new file mode 100644 index 00000000..4f159a84 --- /dev/null +++ b/app/models/relationship.rb @@ -0,0 +1,6 @@ +class Relationship < ActiveRecord::Base + belongs_to :follower, class_name: "User" + belongs_to :followed, class_name: "Profile" + validates :follower_id, presence: true + validates :followed_id, presence: true +end diff --git a/app/models/user.rb b/app/models/user.rb index bd949a7c..ad8f5709 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,11 @@ class User < ActiveRecord::Base has_many :doodads has_many :projects has_many :profiles + has_many :active_relationships, class_name: "Relationship", + foreign_key: "follower_id", + dependent: :destroy + has_many :following, through: :active_relationships, source: :followed + def icid stp = SoftTokenPrincipal.where(soft_token: self.soft_token).first_or_initialize @@ -100,4 +105,20 @@ class User < ActiveRecord::Base # :confirmable, :lockable, :timeoutable and :omniauthable devise :invitable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable + + # Follows a user. + def follow(leader) + active_relationships.create(followed_id: leader.id) + end + + # Unfollows a user. + def unfollow(leader) + active_relationships.find_by(followed_id: leader.id).destroy + end + + # Returns true if the current user is following the leader. + def following?(leader) + following.include?(leader) + end + end diff --git a/app/views/profiles/index.html.haml b/app/views/profiles/index.html.haml index 7cbd574c..18dedfc0 100644 --- a/app/views/profiles/index.html.haml +++ b/app/views/profiles/index.html.haml @@ -17,6 +17,7 @@ - profile.social_links.each do |social_link| = social_link.to_icon.html_safe %p= profile.about + %span #{profile.followers.count} Followers - if policy(profile).destroy? = link_to 'Edit', edit_profile_path(profile) = link_to 'Delete', profile, method: :delete, data: { confirm: 'Are you sure?' } diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 014ae509..ae936275 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -22,3 +22,5 @@ %h2 About #{@profile.name} %p= @profile.about +.stats + %p #{@profile.followers.count} Followers diff --git a/app/views/shared/_stats.html.haml b/app/views/shared/_stats.html.haml new file mode 100644 index 00000000..7f73a4dc --- /dev/null +++ b/app/views/shared/_stats.html.haml @@ -0,0 +1,10 @@ +- @user ||= current_user +.stats + %a{:href => "#{following_user_path(@user)}"} + %strong#following.stat + = @user.following.count + following + -# %a{:href => "#{followers_user_path(@user)}"} + %strong#followers.stat + = @user.followers.count + followers diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 5626e376..a6cdec07 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1,3 +1,7 @@

User

Name: <%= @user.display_name if @user.display_name %>

<%#

Email: <%= @user.email if @user.email %1>

%> + +
+ <%= render 'shared/stats' %> +
diff --git a/config/routes.rb b/config/routes.rb index 68253b16..37fa3f85 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,7 +54,6 @@ Rails.application.routes.draw do get '/play-now', to: 'tables#play_now', as: 'play_now' get '/tutorial', to: 'tables#tutorial', as: 'tutorial' devise_for :users, controllers: { registrations: "users/registrations" } - resources :users get '/loaderio-456644f4db1fcd1e8578be882d2fc476.txt', to: redirect('/assets/loaderio-456644f4db1fcd1e8578be882d2fc476.txt') get '/loaderio-eb4afd672bf5b9af467fbadcba243f26.txt', to: redirect('/assets/loaderio-eb4afd672bf5b9af467fbadcba243f26.txt') get '/calls', to: 'calls#root' @@ -62,4 +61,9 @@ Rails.application.routes.draw do resources :calls, only: :create mount ActionCable.server, at: '/cable' resources :rooms, only: [:new, :create, :show] + resources :users do + member do + get :following + end + end end diff --git a/db/migrate/20231109015600_create_relationships.rb b/db/migrate/20231109015600_create_relationships.rb new file mode 100644 index 00000000..c802c61d --- /dev/null +++ b/db/migrate/20231109015600_create_relationships.rb @@ -0,0 +1,13 @@ +class CreateRelationships < ActiveRecord::Migration[6.1] + 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 diff --git a/db/schema.rb b/db/schema.rb index bc1a0cca..0eda1294 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_11_07_161251) do +ActiveRecord::Schema.define(version: 2023_11_09_015600) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -115,6 +115,16 @@ ActiveRecord::Schema.define(version: 2023_11_07_161251) do t.index ["user_id"], name: "index_projects_on_user_id" end + create_table "relationships", force: :cascade do |t| + t.integer "follower_id" + t.integer "followed_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["followed_id"], name: "index_relationships_on_followed_id" + t.index ["follower_id", "followed_id"], name: "index_relationships_on_follower_id_and_followed_id", unique: true + t.index ["follower_id"], name: "index_relationships_on_follower_id" + end + create_table "seats", force: :cascade do |t| t.integer "table_id" t.integer "user_id" diff --git a/spec/factories/relationships.rb b/spec/factories/relationships.rb new file mode 100644 index 00000000..d6f1dbff --- /dev/null +++ b/spec/factories/relationships.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :relationship do + follower_id 1 + followed_id 1 + end +end diff --git a/spec/models/relationship_spec.rb b/spec/models/relationship_spec.rb new file mode 100644 index 00000000..91d38d9a --- /dev/null +++ b/spec/models/relationship_spec.rb @@ -0,0 +1,5 @@ +# require 'rails_helper' + +# RSpec.describe Relationship, type: :model do +# pending "add some examples to (or delete) #{__FILE__}" +# end