add user follow feature
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -15,3 +15,5 @@ group :development, :test do
|
|||||||
gem "rspec-rails", "~> 5.1"
|
gem "rspec-rails", "~> 5.1"
|
||||||
gem "factory_bot_rails", "~> 6.2"
|
gem "factory_bot_rails", "~> 6.2"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gem "faker", "~> 2.19"
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ GEM
|
|||||||
factory_bot_rails (6.2.0)
|
factory_bot_rails (6.2.0)
|
||||||
factory_bot (~> 6.2.0)
|
factory_bot (~> 6.2.0)
|
||||||
railties (>= 5.0.0)
|
railties (>= 5.0.0)
|
||||||
|
faker (2.19.0)
|
||||||
|
i18n (>= 1.6, < 2)
|
||||||
globalid (1.0.0)
|
globalid (1.0.0)
|
||||||
activesupport (>= 5.0)
|
activesupport (>= 5.0)
|
||||||
i18n (1.10.0)
|
i18n (1.10.0)
|
||||||
@@ -174,8 +176,6 @@ GEM
|
|||||||
rspec-mocks (~> 3.10)
|
rspec-mocks (~> 3.10)
|
||||||
rspec-support (~> 3.10)
|
rspec-support (~> 3.10)
|
||||||
rspec-support (3.11.0)
|
rspec-support (3.11.0)
|
||||||
shoulda-matchers (5.1.0)
|
|
||||||
activesupport (>= 5.2.0)
|
|
||||||
strscan (3.0.1)
|
strscan (3.0.1)
|
||||||
thor (1.2.1)
|
thor (1.2.1)
|
||||||
timeout (0.2.0)
|
timeout (0.2.0)
|
||||||
@@ -193,12 +193,12 @@ DEPENDENCIES
|
|||||||
bootsnap
|
bootsnap
|
||||||
debug
|
debug
|
||||||
factory_bot_rails (~> 6.2)
|
factory_bot_rails (~> 6.2)
|
||||||
|
faker (~> 2.19)
|
||||||
jbuilder
|
jbuilder
|
||||||
pg (~> 1.1)
|
pg (~> 1.1)
|
||||||
puma (~> 5.0)
|
puma (~> 5.0)
|
||||||
rails (~> 7.0.2, >= 7.0.2.2)
|
rails (~> 7.0.2, >= 7.0.2.2)
|
||||||
rspec-rails (~> 5.1)
|
rspec-rails (~> 5.1)
|
||||||
shoulda-matchers (~> 5.1)
|
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 3.1.1p18
|
ruby 3.1.1p18
|
||||||
|
|||||||
53
app/controllers/user_follows_controller.rb
Normal file
53
app/controllers/user_follows_controller.rb
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
class UserFollowsController < ApplicationController
|
||||||
|
before_action :set_user_follow, only: %i[ show update destroy ]
|
||||||
|
|
||||||
|
# GET /user_follows
|
||||||
|
# GET /user_follows.json
|
||||||
|
def index
|
||||||
|
@user_follows = UserFollow.all
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /user_follows/1
|
||||||
|
# GET /user_follows/1.json
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /user_follows
|
||||||
|
# POST /user_follows.json
|
||||||
|
def create
|
||||||
|
@user_follow = UserFollow.new(user_follow_params)
|
||||||
|
|
||||||
|
if @user_follow.save
|
||||||
|
render :show, status: :created, location: @user_follow
|
||||||
|
else
|
||||||
|
render json: @user_follow.errors, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /user_follows/1
|
||||||
|
# PATCH/PUT /user_follows/1.json
|
||||||
|
def update
|
||||||
|
if @user_follow.update(user_follow_params)
|
||||||
|
render :show, status: :ok, location: @user_follow
|
||||||
|
else
|
||||||
|
render json: @user_follow.errors, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /user_follows/1
|
||||||
|
# DELETE /user_follows/1.json
|
||||||
|
def destroy
|
||||||
|
@user_follow.destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
def set_user_follow
|
||||||
|
@user_follow = UserFollow.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow a list of trusted parameters through.
|
||||||
|
def user_follow_params
|
||||||
|
params.require(:user_follow).permit(:follower_id, :followed_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
4
app/models/user_follow.rb
Normal file
4
app/models/user_follow.rb
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
class UserFollow < ApplicationRecord
|
||||||
|
belongs_to :follower, class_name: 'User'
|
||||||
|
belongs_to :followed, class_name: 'User'
|
||||||
|
end
|
||||||
2
app/views/user_follows/_user_follow.json.jbuilder
Normal file
2
app/views/user_follows/_user_follow.json.jbuilder
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
json.extract! user_follow, :id, :follower_id, :followed_id, :created_at, :updated_at
|
||||||
|
json.url user_follow_url(user_follow, format: :json)
|
||||||
1
app/views/user_follows/index.json.jbuilder
Normal file
1
app/views/user_follows/index.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
json.array! @user_follows, partial: "user_follows/user_follow", as: :user_follow
|
||||||
1
app/views/user_follows/show.json.jbuilder
Normal file
1
app/views/user_follows/show.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
json.partial! "user_follows/user_follow", user_follow: @user_follow
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
|
resources :user_follows, only: [:create, :destroy]
|
||||||
resources :users, only: [:show]
|
resources :users, only: [:show]
|
||||||
|
|
||||||
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
|
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
|
||||||
|
|||||||
10
db/migrate/20220227175028_create_user_follows.rb
Normal file
10
db/migrate/20220227175028_create_user_follows.rb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class CreateUserFollows < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
create_table :user_follows do |t|
|
||||||
|
t.references :follower, references: :users, foreign_key: { to_table: :users }
|
||||||
|
t.references :followed, references: :users, foreign_key: { to_table: :users }
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
13
db/schema.rb
generated
13
db/schema.rb
generated
@@ -10,10 +10,19 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.0].define(version: 2022_02_27_172543) do
|
ActiveRecord::Schema[7.0].define(version: 2022_02_27_175028) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
create_table "user_follows", force: :cascade do |t|
|
||||||
|
t.bigint "follower_id"
|
||||||
|
t.bigint "followed_id"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["followed_id"], name: "index_user_follows_on_followed_id"
|
||||||
|
t.index ["follower_id"], name: "index_user_follows_on_follower_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "username", limit: 14, null: false
|
t.string "username", limit: 14, null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
@@ -21,4 +30,6 @@ ActiveRecord::Schema[7.0].define(version: 2022_02_27_172543) do
|
|||||||
t.index ["username"], name: "index_users_on_username"
|
t.index ["username"], name: "index_users_on_username"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "user_follows", "users", column: "followed_id"
|
||||||
|
add_foreign_key "user_follows", "users", column: "follower_id"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
User.find_or_create_by(username: 'xpto')
|
|
||||||
User.find_or_create_by(username: 'admin')
|
User.find_or_create_by(username: 'admin')
|
||||||
User.find_or_create_by(username: 'geonizeli')
|
xpto = User.find_or_create_by(username: 'xpto')
|
||||||
|
geonizeli = User.find_or_create_by(username: 'geonizeli')
|
||||||
|
|
||||||
|
UserFollow.find_or_create_by(follower_id: xpto.id, followed_id: geonizeli.id)
|
||||||
|
UserFollow.find_or_create_by(follower_id: geonizeli.id, followed_id: xpto.id)
|
||||||
|
|||||||
6
spec/factories/user_follows.rb
Normal file
6
spec/factories/user_follows.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :user_follow do
|
||||||
|
follower { nil }
|
||||||
|
followed { nil }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :user do
|
factory :user do
|
||||||
username { "xpto" }
|
username { Faker::Internet.username.gsub(/[^0-9a-z ]/i, '') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
67
spec/requests/user_follows_spec.rb
Normal file
67
spec/requests/user_follows_spec.rb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe "/user_follows", type: :request do
|
||||||
|
let(:followed) { create(:user) }
|
||||||
|
let(:follower) { create(:user) }
|
||||||
|
|
||||||
|
let(:valid_attributes) {
|
||||||
|
{
|
||||||
|
followed_id: followed.id,
|
||||||
|
follower_id: follower.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:invalid_attributes) {
|
||||||
|
{
|
||||||
|
followed_id: followed.id,
|
||||||
|
follower_id: 'follower.id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:valid_headers) {
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe "POST /create" do
|
||||||
|
context "with valid parameters" do
|
||||||
|
it "creates a new UserFollow" do
|
||||||
|
expect {
|
||||||
|
post user_follows_url,
|
||||||
|
params: { user_follow: valid_attributes }, headers: valid_headers, as: :json
|
||||||
|
}.to change(UserFollow, :count).by(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a JSON response with the new user_follow" do
|
||||||
|
post user_follows_url,
|
||||||
|
params: { user_follow: valid_attributes }, headers: valid_headers, as: :json
|
||||||
|
expect(response).to have_http_status(:created)
|
||||||
|
expect(response.content_type).to match(a_string_including("application/json"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with invalid parameters" do
|
||||||
|
it "does not create a new UserFollow" do
|
||||||
|
expect {
|
||||||
|
post user_follows_url,
|
||||||
|
params: { user_follow: invalid_attributes }, as: :json
|
||||||
|
}.to change(UserFollow, :count).by(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a JSON response with errors for the new user_follow" do
|
||||||
|
post user_follows_url,
|
||||||
|
params: { user_follow: invalid_attributes }, headers: valid_headers, as: :json
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(response.content_type).to match(a_string_including("application/json"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "DELETE /destroy" do
|
||||||
|
it "destroys the requested user_follow" do
|
||||||
|
user_follow = UserFollow.create! valid_attributes
|
||||||
|
expect {
|
||||||
|
delete user_follow_url(user_follow), headers: valid_headers, as: :json
|
||||||
|
}.to change(UserFollow, :count).by(-1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
13
spec/routing/user_follows_routing_spec.rb
Normal file
13
spec/routing/user_follows_routing_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe UserFollowsController, type: :routing do
|
||||||
|
describe "routing" do
|
||||||
|
it "routes to #create" do
|
||||||
|
expect(post: "/user_follows").to route_to("user_follows#create")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "routes to #destroy" do
|
||||||
|
expect(delete: "/user_follows/1").to route_to("user_follows#destroy", id: "1")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user