Skip to content

Commit

Permalink
API CRUD endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
yshmarov committed Apr 18, 2023
1 parent c846e08 commit de10124
Show file tree
Hide file tree
Showing 27 changed files with 402 additions and 3 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
user = User.first
api_token = user.api_tokens.create!
token = api_token.token
MySecretApiToken = api_token.token

curl -X GET localhost:3000/api/v1/home/index.json -H "Authorization: Bearer b7b0cee0299d486ab104bcccd813940e"
```sh
# check connection
curl -X GET localhost:3000/api/v1/home/index.json -H "Authorization: Bearer MySecretApiToken"

# posts#index
curl -X GET localhost:3000/api/v1/posts.json -H "Authorization: Bearer MySecretApiToken"

# posts#show
curl -X GET localhost:3000/api/v1/posts/1.json -H "Authorization: Bearer MySecretApiToken"

# posts#create
curl -X POST -H "Content-Type: application/json" -d '{"post": {"title": "via api"}}' localhost:3000/api/v1/posts.json -H "Authorization: Bearer MySecretApiToken"

# posts#destroy
curl -X DELETE localhost:3000/api/v1/posts/3.json -H "Authorization: Bearer MySecretApiToken"

# posts#update
curl -X PATCH -H "Content-Type: application/json" -d '{"post": {"title": "via api edited 2"}}' localhost:3000/api/v1/posts/4.json -H "Authorization: Bearer MySecretApiToken"
```
8 changes: 8 additions & 0 deletions app/controllers/api/v1/authenticated_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class Api::V1::AuthenticatedController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found

protect_from_forgery with: :null_session

before_action :authenticate

attr_reader :current_api_token, :current_user
Expand All @@ -19,4 +23,8 @@ def authenticate_user_with_token
def handle_bad_authentication
render json: { message: "Bad credentials" }, status: :unauthorized
end

def handle_not_found
render json: { message: "Record not found" }, status: :not_found
end
end
64 changes: 64 additions & 0 deletions app/controllers/api/v1/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class Api::V1::PostsController < Api::V1::AuthenticatedController
before_action :set_post, only: %i[ show edit update destroy ]

# GET /posts or /posts.json
def index
@posts = current_user.posts.all
end

# GET /posts/1 or /posts/1.json
def show
end

# GET /posts/new
def new
@post = current_user.posts.new
end

# GET /posts/1/edit
def edit
end

# POST /posts or /posts.json
def create
@post = current_user.posts.new(post_params)

respond_to do |format|
if @post.save
format.json { render :show, status: :created, location: @post }
else
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /posts/1 or /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.json { render :show, status: :ok, location: @post }
else
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end

# DELETE /posts/1 or /posts/1.json
def destroy
@post.destroy
respond_to do |format|
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = current_user.posts.find(params[:id])
end

# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:title, :body)
end
end
71 changes: 71 additions & 0 deletions app/controllers/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class PostsController < ApplicationController
# skip_before_action :authenticate_user!
before_action :set_post, only: %i[ show edit update destroy ]

# GET /posts or /posts.json
def index
@posts = Post.all
end

# GET /posts/1 or /posts/1.json
def show
end

# GET /posts/new
def new
@post = current_user.posts.new
end

# GET /posts/1/edit
def edit
end

# POST /posts or /posts.json
def create
@post = current_user.posts.new(post_params)

respond_to do |format|
if @post.save
format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /posts/1 or /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end

# DELETE /posts/1 or /posts/1.json
def destroy
@post.destroy

respond_to do |format|
format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
format.json { head :no_content }
end
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(:title, :body)
end
end
2 changes: 2 additions & 0 deletions app/helpers/posts_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module PostsHelper
end
4 changes: 4 additions & 0 deletions app/models/post.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Post < ApplicationRecord
validates :title, presence: true
belongs_to :user
end
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :api_tokens
has_many :posts
end
2 changes: 2 additions & 0 deletions app/views/api/v1/posts/_post.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! post, :id, :user_id, :title, :body, :created_at, :updated_at
json.url post_url(post, format: :json)
1 change: 1 addition & 0 deletions app/views/api/v1/posts/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @posts, partial: "api/v1/posts/post", as: :post
1 change: 1 addition & 0 deletions app/views/api/v1/posts/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "api/v1/posts/post", post: @post
1 change: 1 addition & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<%= link_to "Log in", new_user_session_path %>
<%= link_to "Register", new_user_registration_path %>
<% end %>
<hr>
<%= yield %>
</body>
</html>
27 changes: 27 additions & 0 deletions app/views/posts/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%= form_with(model: post) do |form| %>
<% if post.errors.any? %>
<div style="color: red">
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

<ul>
<% post.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :title, style: "display: block" %>
<%= form.text_field :title %>
</div>

<div>
<%= form.label :body, style: "display: block" %>
<%= form.text_area :body %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
17 changes: 17 additions & 0 deletions app/views/posts/_post.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div id="<%= dom_id post %>">
<p>
<strong>User:</strong>
<%= post.user_id %>
</p>

<p>
<strong>Title:</strong>
<%= post.title %>
</p>

<p>
<strong>Body:</strong>
<%= post.body %>
</p>

</div>
3 changes: 3 additions & 0 deletions app/views/posts/_post.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
json.extract! post, :id, :title, :body, :created_at, :updated_at
json.user_email post.user.email
json.url post_url(post, format: :json)
10 changes: 10 additions & 0 deletions app/views/posts/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Editing post</h1>

<%= render "form", post: @post %>

<br>

<div>
<%= link_to "Show this post", @post %> |
<%= link_to "Back to posts", posts_path %>
</div>
14 changes: 14 additions & 0 deletions app/views/posts/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<h1>Posts</h1>

<div id="posts">
<% @posts.each do |post| %>
<%= render post %>
<p>
<%= link_to "Show this post", post %>
</p>
<% end %>
</div>

<%= link_to "New post", new_post_path %>
1 change: 1 addition & 0 deletions app/views/posts/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @posts, partial: "posts/post", as: :post
9 changes: 9 additions & 0 deletions app/views/posts/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>New post</h1>

<%= render "form", post: @post %>

<br>

<div>
<%= link_to "Back to posts", posts_path %>
</div>
10 changes: 10 additions & 0 deletions app/views/posts/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @post %>

<div>
<%= link_to "Edit this post", edit_post_path(@post) %> |
<%= link_to "Back to posts", posts_path %>
<%= button_to "Destroy this post", @post, method: :delete %>
</div>
1 change: 1 addition & 0 deletions app/views/posts/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "posts/post", post: @post
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Rails.application.routes.draw do
resources :posts
devise_for :users
root 'static_pages#landing_page'
get 'dashboard', to: 'static_pages#dashboard'
Expand All @@ -7,6 +8,7 @@
namespace :api do
namespace :v1 do
defaults format: :json do
resources :posts, only: [:index, :show, :create, :update, :destroy]
get "home/index", to: "home#index"
end
end
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20230418092206_create_posts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreatePosts < ActiveRecord::Migration[7.0]
def change
create_table :posts do |t|
t.references :user, null: false, foreign_key: true
t.string :title
t.text :body

t.timestamps
end
end
end
12 changes: 11 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit de10124

Please sign in to comment.