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
|
Rails.application.routes.draw do
|
||||||
|
resources :posts, only: [:index, :show, :create]
|
||||||
resources :user_follows, only: [:create, :destroy]
|
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
|
|
||||||
end
|
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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
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|
|
create_table "user_follows", force: :cascade do |t|
|
||||||
t.bigint "follower_id"
|
t.bigint "follower_id"
|
||||||
t.bigint "followed_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"
|
t.index ["username"], name: "index_users_on_username"
|
||||||
end
|
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: "followed_id"
|
||||||
add_foreign_key "user_follows", "users", column: "follower_id"
|
add_foreign_key "user_follows", "users", column: "follower_id"
|
||||||
end
|
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: 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)
|
||||||
|
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