add post
This commit is contained in:
53
app/controllers/posts_controller.rb
Normal file
53
app/controllers/posts_controller.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
class PostsController < ApplicationController
|
||||
before_action :set_post, only: %i[ show update destroy ]
|
||||
|
||||
# GET /posts
|
||||
# GET /posts.json
|
||||
def index
|
||||
@posts = Post.all
|
||||
end
|
||||
|
||||
# GET /posts/1
|
||||
# GET /posts/1.json
|
||||
def show
|
||||
end
|
||||
|
||||
# POST /posts
|
||||
# POST /posts.json
|
||||
def create
|
||||
@post = Post.new(post_params)
|
||||
|
||||
if @post.save
|
||||
render :show, status: :created, location: @post
|
||||
else
|
||||
render json: @post.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /posts/1
|
||||
# PATCH/PUT /posts/1.json
|
||||
def update
|
||||
if @post.update(post_params)
|
||||
render :show, status: :ok, location: @post
|
||||
else
|
||||
render json: @post.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /posts/1
|
||||
# DELETE /posts/1.json
|
||||
def destroy
|
||||
@post.destroy
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_post
|
||||
@post = Post.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def post_params
|
||||
params.require(:post).permit(:content, :user_id, :quoted_post_id)
|
||||
end
|
||||
end
|
||||
27
app/models/post.rb
Normal file
27
app/models/post.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
class Post < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :quoted_post, optional: true, class_name: 'Post'
|
||||
|
||||
validates :content, length: { maximum: 777 }
|
||||
validates :content, presence: true, if: :quoted_post?
|
||||
|
||||
def kind
|
||||
if quoted_post?
|
||||
:quoted_post
|
||||
elsif repost?
|
||||
:repost
|
||||
else
|
||||
:post
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def quoted_post?
|
||||
content.present? && quoted_post_id
|
||||
end
|
||||
|
||||
def repost?
|
||||
content.blank? && quoted_post_id
|
||||
end
|
||||
end
|
||||
4
app/views/posts/_post.json.jbuilder
Normal file
4
app/views/posts/_post.json.jbuilder
Normal file
@@ -0,0 +1,4 @@
|
||||
json.extract! post, :id, :content, :user_id, :created_at, :updated_at
|
||||
json.url post_url(post, format: :json)
|
||||
|
||||
json.quoted_post(post.quoted_post)
|
||||
1
app/views/posts/index.json.jbuilder
Normal file
1
app/views/posts/index.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
||||
json.array! @posts, partial: "posts/post", as: :post
|
||||
1
app/views/posts/show.json.jbuilder
Normal file
1
app/views/posts/show.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
||||
json.partial! "posts/post", post: @post
|
||||
@@ -1,6 +1,5 @@
|
||||
Rails.application.routes.draw do
|
||||
resources :posts, only: [:index, :show, :create]
|
||||
resources :user_follows, only: [:create, :destroy]
|
||||
resources :users, only: [:show]
|
||||
|
||||
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
|
||||
end
|
||||
|
||||
11
db/migrate/20220227194054_create_posts.rb
Normal file
11
db/migrate/20220227194054_create_posts.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreatePosts < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :posts do |t|
|
||||
t.text :content, null: true
|
||||
t.references :user, null: false, references: :user, foreign_key: { to_table: :users }
|
||||
t.references :quoted_post, null: true, references: :post, foreign_key: { to_table: :posts }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
14
db/schema.rb
generated
14
db/schema.rb
generated
@@ -10,10 +10,20 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2022_02_27_175028) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2022_02_27_194054) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "posts", force: :cascade do |t|
|
||||
t.text "content"
|
||||
t.bigint "user_id", null: false
|
||||
t.bigint "quoted_post_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["quoted_post_id"], name: "index_posts_on_quoted_post_id"
|
||||
t.index ["user_id"], name: "index_posts_on_user_id"
|
||||
end
|
||||
|
||||
create_table "user_follows", force: :cascade do |t|
|
||||
t.bigint "follower_id"
|
||||
t.bigint "followed_id"
|
||||
@@ -30,6 +40,8 @@ ActiveRecord::Schema[7.0].define(version: 2022_02_27_175028) do
|
||||
t.index ["username"], name: "index_users_on_username"
|
||||
end
|
||||
|
||||
add_foreign_key "posts", "posts", column: "quoted_post_id"
|
||||
add_foreign_key "posts", "users"
|
||||
add_foreign_key "user_follows", "users", column: "followed_id"
|
||||
add_foreign_key "user_follows", "users", column: "follower_id"
|
||||
end
|
||||
|
||||
@@ -4,3 +4,6 @@ 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)
|
||||
|
||||
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)
|
||||
7
spec/factories/posts.rb
Normal file
7
spec/factories/posts.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
FactoryBot.define do
|
||||
factory :post do
|
||||
content { Faker::Lorem.paragraph }
|
||||
user
|
||||
quoted_post { nil }
|
||||
end
|
||||
end
|
||||
31
spec/models/post_spec.rb
Normal file
31
spec/models/post_spec.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Post, type: :model do
|
||||
describe '#kind' do
|
||||
context 'when post have other post reference and a content' do
|
||||
it 'returns :quoted_post' do
|
||||
quoted_post = create(:post)
|
||||
post = create(:post, quoted_post: quoted_post)
|
||||
|
||||
expect(post.kind).to eq(:quoted_post)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when post have other post reference and dont have a content' do
|
||||
it 'returns :repost' do
|
||||
quoted_post = create(:post)
|
||||
post = create(:post, quoted_post: quoted_post, content: nil)
|
||||
|
||||
expect(post.kind).to eq(:repost)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when post dont have other post reference and have a content' do
|
||||
it 'returns :post' do
|
||||
post = create(:post)
|
||||
|
||||
expect(post.kind).to eq(:post)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
88
spec/requests/posts_spec.rb
Normal file
88
spec/requests/posts_spec.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
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
|
||||
let(:quoted_post) { create(:post) }
|
||||
|
||||
let(:valid_attributes) {
|
||||
{
|
||||
content: "Quo dolorem recusandae. Vero laborum deleniti. Qui ipsam illum.",
|
||||
user_id: create(:user).id,
|
||||
}
|
||||
}
|
||||
|
||||
let(:invalid_attributes) {
|
||||
{
|
||||
content: "Quo dolorem recusandae. Vero laborum deleniti. Qui ipsam illum."
|
||||
}
|
||||
}
|
||||
|
||||
# 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) {
|
||||
{}
|
||||
}
|
||||
|
||||
describe "GET /index" do
|
||||
it "renders a successful response" do
|
||||
Post.create! valid_attributes
|
||||
get posts_url, headers: valid_headers, as: :json
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /show" do
|
||||
it "renders a successful response" do
|
||||
post = Post.create! valid_attributes
|
||||
get post_url(post), as: :json
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /create" do
|
||||
context "with valid parameters" do
|
||||
it "creates a new Post" do
|
||||
expect {
|
||||
post posts_url,
|
||||
params: { post: valid_attributes }, headers: valid_headers, as: :json
|
||||
}.to change(Post, :count).by(1)
|
||||
end
|
||||
|
||||
it "renders a JSON response with the new post" do
|
||||
post posts_url,
|
||||
params: { post: 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 Post" do
|
||||
expect {
|
||||
post posts_url,
|
||||
params: { post: invalid_attributes }, as: :json
|
||||
}.to change(Post, :count).by(0)
|
||||
end
|
||||
|
||||
it "renders a JSON response with errors for the new post" do
|
||||
post posts_url,
|
||||
params: { post: 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
|
||||
end
|
||||
18
spec/routing/posts_routing_spec.rb
Normal file
18
spec/routing/posts_routing_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe PostsController, type: :routing do
|
||||
describe "routing" do
|
||||
it "routes to #index" do
|
||||
expect(get: "/posts").to route_to("posts#index")
|
||||
end
|
||||
|
||||
it "routes to #show" do
|
||||
expect(get: "/posts/1").to route_to("posts#show", id: "1")
|
||||
end
|
||||
|
||||
|
||||
it "routes to #create" do
|
||||
expect(post: "/posts").to route_to("posts#create")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user