add posts scope filter

This commit is contained in:
João Victor Geonizeli
2022-02-28 11:22:37 -03:00
parent e1f96c04a4
commit bf3253dc9e
5 changed files with 71 additions and 24 deletions

View File

@@ -2,7 +2,7 @@ class PostsController < ApplicationController
# GET /posts # GET /posts
# GET /posts.json # GET /posts.json
def index def index
@posts = Post.all @posts = PostsQueryResolverService.call(query_params, current_user)
end end
# GET /posts/1 # GET /posts/1
@@ -14,7 +14,10 @@ class PostsController < ApplicationController
# POST /posts # POST /posts
# POST /posts.json # POST /posts.json
def create def create
@post = Post.new(post_params) @post = Post.new({
user: current_user,
**post_params
})
if @post.save if @post.save
render :show, status: :created, location: @post render :show, status: :created, location: @post
@@ -25,11 +28,11 @@ class PostsController < ApplicationController
private private
# Only allow a list of trusted parameters through. def query_params
params.permit(:scope) || {}
end
def post_params def post_params
{ params.require(:post).permit(:content, :quoted_post_id)
user: current_user,
**params.require(:post).permit(:content, :quoted_post_id)
}
end end
end end

View File

@@ -0,0 +1,22 @@
class PostsQueryResolverService
attr_reader :filter, :current_user
def initialize(filter, current_user)
@filter = filter
@current_user = current_user
end
def self.call(filter, current_user)
new(filter, current_user).call
end
def call
scope = Post.all
if filter[:scope] == 'follows' && current_user
scope = scope.by_user_follows(current_user)
end
scope
end
end

View File

@@ -6,4 +6,5 @@ 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) UserFollow.find_or_create_by(follower_id: geonizeli.id, followed_id: xpto.id)
first_post = Post.find_or_create_by(content: 'Hello World!', user_id: xpto.id) first_post = Post.find_or_create_by(content: 'Hello World!', user_id: xpto.id)
Post.find_or_create_by(content: 'Hello World!', user_id: xpto.id, quoted_post_id: first_post.id) Post.find_or_create_by(content: 'Hello World!', user_id: xpto.id, quoted_post_id: first_post.id)
Post.find_or_create_by(content: 'Hello World!', user_id: geonizeli.id)

View File

@@ -1,17 +1,5 @@
require 'rails_helper' require 'rails_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to test the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
RSpec.describe "/posts", type: :request do RSpec.describe "/posts", type: :request do
let(:user) { create(:user) } let(:user) { create(:user) }
@@ -27,10 +15,6 @@ RSpec.describe "/posts", type: :request do
} }
} }
# This should return the minimal set of values that should be in the headers
# in order to pass any filters (e.g. authentication) defined in
# PostsController, or in your router and rack
# middleware. Be sure to keep this updated too.
let(:valid_headers) { let(:valid_headers) {
{ {
Cookie: "user_id=#{user.id}" Cookie: "user_id=#{user.id}"

View File

@@ -0,0 +1,37 @@
require 'rails_helper'
RSpec.describe PostsQueryResolverService, type: :service do
context '#call' do
let(:current_user) { create(:user) }
context 'when without filter' do
it 'returns all posts' do
followed_user = create(:user)
create(:user_follow, follower_id: current_user.id, followed_id: followed_user.id)
post1 = create(:post, user_id: followed_user.id)
post2 = create(:post, user_id: followed_user.id)
post3 = create(:post)
expect(
described_class.call({}, current_user)
).to eq([post1, post2, post3])
end
end
context 'when scoping by user follows' do
it 'returns only posts from user follows' do
followed_user = create(:user)
create(:user_follow, follower_id: current_user.id, followed_id: followed_user.id)
post1 = create(:post, user_id: followed_user.id)
post2 = create(:post, user_id: followed_user.id)
post3 = create(:post)
expect(
described_class.call({ scope: 'follows' }, current_user)
).to eq([post1, post2])
end
end
end
end