feat: APIs for Articles (#4777)

Fixes: #4802
This commit is contained in:
Tejaswini Chile
2022-06-13 15:56:49 +05:30
committed by GitHub
parent 2198930185
commit ae72757d23
23 changed files with 511 additions and 42 deletions

View File

@@ -0,0 +1,48 @@
class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController
before_action :portal
before_action :fetch_article, except: [:index, :create]
def index
@articles = @portal.articles
@articles.search(list_params) if params[:payload].present?
end
def create
@article = @portal.articles.create!(article_params)
end
def edit; end
def show; end
def update
@article.update!(article_params)
end
def destroy
@article.destroy!
head :ok
end
private
def fetch_article
@article = @portal.articles.find(params[:id])
end
def portal
@portal ||= Current.account.portals.find_by(slug: params[:portal_id])
end
def article_params
params.require(:article).permit(
:title, :content, :description, :position, :category_id, :author_id
)
end
def list_params
params.require(:payload).permit(
:category_slug, :locale, :query
)
end
end

View File

@@ -3,7 +3,7 @@ class Api::V1::Accounts::CategoriesController < Api::V1::Accounts::BaseControlle
before_action :fetch_category, except: [:index, :create]
def index
@categories = @portal.categories
@categories = @portal.categories.search(params)
end
def create
@@ -31,7 +31,7 @@ class Api::V1::Accounts::CategoriesController < Api::V1::Accounts::BaseControlle
def category_params
params.require(:category).permit(
:name, :description, :position
:name, :description, :position, :slug, :locale
)
end
end

View File

@@ -2,25 +2,34 @@
#
# Table name: articles
#
# id :bigint not null, primary key
# content :text
# description :text
# status :integer
# title :string
# views :integer
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
# author_id :integer
# category_id :integer
# folder_id :integer
# portal_id :integer not null
# id :bigint not null, primary key
# content :text
# description :text
# status :integer
# title :string
# views :integer
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
# author_id :bigint
# category_id :integer
# folder_id :integer
# portal_id :integer not null
#
# Indexes
#
# index_articles_on_author_id (author_id)
#
# Foreign Keys
#
# fk_rails_... (author_id => users.id)
#
class Article < ApplicationRecord
include PgSearch::Model
belongs_to :account
belongs_to :category
belongs_to :portal
belongs_to :folder
belongs_to :author, class_name: 'User'
before_validation :ensure_account_id
@@ -32,6 +41,36 @@ class Article < ApplicationRecord
enum status: { draft: 0, published: 1 }
scope :search_by_category_slug, ->(category_slug) { where(categories: { slug: category_slug }) if category_slug.present? }
scope :search_by_category_locale, ->(locale) { where(categories: { locale: locale }) if locale.present? }
# TODO: if text search slows down https://www.postgresql.org/docs/current/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS
pg_search_scope(
:text_search,
against: %i[
title
description
content
],
using: {
tsearch: {
prefix: true
}
}
)
def self.search(params)
records = joins(
:category
).search_by_category_slug(params[:category_slug]).search_by_category_locale(params[:locale])
records.text_search(params[:query]) if params[:query].present?
records.page(current_page(params))
end
def self.current_page(params)
params[:page] || 1
end
private
def ensure_account_id

View File

@@ -2,20 +2,22 @@
#
# Table name: categories
#
# id :bigint not null, primary key
# description :text
# locale :string default("en")
# name :string
# position :integer
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
# portal_id :integer not null
# id :bigint not null, primary key
# description :text
# locale :string default("en")
# name :string
# position :integer
# slug :string not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :integer not null
# portal_id :integer not null
#
# Indexes
#
# index_categories_on_locale (locale)
# index_categories_on_locale_and_account_id (locale,account_id)
# index_categories_on_locale (locale)
# index_categories_on_locale_and_account_id (locale,account_id)
# index_categories_on_slug_and_locale_and_portal_id (slug,locale,portal_id) UNIQUE
#
class Category < ApplicationRecord
belongs_to :account
@@ -25,7 +27,20 @@ class Category < ApplicationRecord
before_validation :ensure_account_id
validates :account_id, presence: true
validates :slug, presence: true
validates :name, presence: true
validates :locale, uniqueness: { scope: %i[slug portal_id],
message: 'should be unique in the category and portal' }
scope :search_by_locale, ->(locale) { where(locale: locale) if locale.present? }
def self.search(params)
search_by_locale(params[:locale]).page(current_page(params)).order(position: :asc)
end
def self.current_page(params)
params[:page] || 1
end
private

View File

@@ -92,6 +92,7 @@ class User < ApplicationRecord
has_many :portals, through: :portals_members
has_many :team_members, dependent: :destroy_async
has_many :teams, through: :team_members
has_many :articles, foreign_key: 'author_id', dependent: :nullify
before_validation :set_password_and_uid, on: :create

View File

@@ -0,0 +1,20 @@
json.id article.id
json.category_id article.category_id
json.title article.title
json.content article.content
json.description article.description
json.status article.status
json.account_id article.account_id
if article.portal.present?
json.portal do
json.partial! 'api/v1/accounts/portals/portal.json.jbuilder', portal: article.portal
end
end
json.views article.views
if article.author.present?
json.author do
json.partial! 'api/v1/models/agent.json.jbuilder', resource: article.author
end
end

View File

@@ -0,0 +1,3 @@
json.payload do
json.partial! 'article', article: @article
end

View File

@@ -0,0 +1,3 @@
json.payload do
json.partial! 'article', article: @article
end

View File

@@ -0,0 +1,3 @@
json.payload do
json.array! @articles, partial: 'article', as: :article
end

View File

@@ -0,0 +1,3 @@
json.payload do
json.partial! 'article', article: @article
end

View File

@@ -0,0 +1,3 @@
json.payload do
json.partial! 'article', article: @article
end

View File

@@ -1,5 +1,7 @@
json.id category.id
json.name category.name
json.slug category.slug
json.locale category.locale
json.description category.description
json.position category.position
json.account_id category.account_id