#234 feat: Wiki 有無判定軽量化(#233)

Merged
みてるぞ merged 1 commits from #233 into main 3 weeks ago
  1. +7
    -7
      backend/app/controllers/posts_controller.rb
  2. +13
    -5
      backend/spec/requests/posts_spec.rb
  3. +10
    -2
      frontend/src/components/TagLink.tsx
  4. +1
    -0
      frontend/src/types.ts

+ 7
- 7
backend/app/controllers/posts_controller.rb View File

@@ -36,7 +36,7 @@ class PostsController < ApplicationController


render json: { posts: posts.map { |post| render json: { posts: posts.map { |post|
post.as_json(include: { tags: { only: [:id, :category, :post_count], post.as_json(include: { tags: { only: [:id, :category, :post_count],
methods: [:name] } }).tap do |json|
methods: [:name, :has_wiki] } }).tap do |json|
json['thumbnail'] = json['thumbnail'] =
if post.thumbnail.attached? if post.thumbnail.attached?
rails_storage_proxy_url(post.thumbnail, only_path: false) rails_storage_proxy_url(post.thumbnail, only_path: false)
@@ -59,7 +59,7 @@ class PostsController < ApplicationController


render json: (post render json: (post
.as_json(include: { tags: { only: [:id, :category, :post_count], .as_json(include: { tags: { only: [:id, :category, :post_count],
methods: [:name] } })
methods: [:name, :has_wiki] } })
.merge(viewed:)) .merge(viewed:))
end end


@@ -100,7 +100,7 @@ class PostsController < ApplicationController
tags = Tag.expand_parent_tags(tags) tags = Tag.expand_parent_tags(tags)
sync_post_tags!(post, tags) sync_post_tags!(post, tags)
render json: post.as_json(include: { tags: { only: [:id, :category, :post_count], render json: post.as_json(include: { tags: { only: [:id, :category, :post_count],
methods: [:name] } }),
methods: [:name, :has_wiki] } }),
status: :created status: :created
else else
render json: { errors: post.errors.full_messages }, status: :unprocessable_entity render json: { errors: post.errors.full_messages }, status: :unprocessable_entity
@@ -162,7 +162,7 @@ class PostsController < ApplicationController
pts.each do |pt| pts.each do |pt|
events << Event.new( events << Event.new(
post: pt.post, post: pt.post,
tag: pt.tag.as_json(only: [:id, :category], methods: [:name]),
tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]),
user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name }, user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name },
change_type: 'add', change_type: 'add',
timestamp: pt.created_at) timestamp: pt.created_at)
@@ -170,7 +170,7 @@ class PostsController < ApplicationController
if pt.discarded_at if pt.discarded_at
events << Event.new( events << Event.new(
post: pt.post, post: pt.post,
tag: pt.tag.as_json(only: [:id, :category], methods: [:name]),
tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]),
user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name }, user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name },
change_type: 'remove', change_type: 'remove',
timestamp: pt.discarded_at) timestamp: pt.discarded_at)
@@ -255,7 +255,7 @@ class PostsController < ApplicationController


if path.include?(tag_id) if path.include?(tag_id)
return tag.as_json(only: [:id, :category, :post_count], return tag.as_json(only: [:id, :category, :post_count],
methods: [:name]).merge(children: [])
methods: [:name, :has_wiki]).merge(children: [])
end end


if memo.key?(tag_id) if memo.key?(tag_id)
@@ -268,7 +268,7 @@ class PostsController < ApplicationController
children = child_ids.filter_map { |cid| build_node.(cid, new_path) } children = child_ids.filter_map { |cid| build_node.(cid, new_path) }


memo[tag_id] = tag.as_json(only: [:id, :category, :post_count], memo[tag_id] = tag.as_json(only: [:id, :category, :post_count],
methods: [:name]).merge(children:)
methods: [:name, :has_wiki]).merge(children:)
end end


root_ids.filter_map { |id| build_node.call(id, []) } root_ids.filter_map { |id| build_node.call(id, []) }


+ 13
- 5
backend/spec/requests/posts_spec.rb View File

@@ -54,9 +54,9 @@ RSpec.describe 'Posts API', type: :request do
# 全postの全tagが name を含むこと # 全postの全tagが name を含むこと
expect(posts).not_to be_empty expect(posts).not_to be_empty
posts.each do |p| posts.each do |p|
expect(p["tags"]).to be_an(Array)
p["tags"].each do |t|
expect(t).to include("name", "category")
expect(p['tags']).to be_an(Array)
p['tags'].each do |t|
expect(t).to include('name', 'category', 'has_wiki')
end end
end end
expect(json['count']).to be_an(Integer) expect(json['count']).to be_an(Integer)
@@ -71,11 +71,19 @@ RSpec.describe 'Posts API', type: :request do
get "/posts", params: { tags: "spec_tag" } get "/posts", params: { tags: "spec_tag" }


expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
ids = json.fetch("posts").map { |p| p["id"] }
posts = json.fetch('posts')
ids = posts.map { |p| p['id'] }


expect(ids).to include(hit_post.id) expect(ids).to include(hit_post.id)
expect(ids).not_to include(miss_post.id) expect(ids).not_to include(miss_post.id)
expect(json['count']).to be_an(Integer) expect(json['count']).to be_an(Integer)

posts.each do |p|
expect(p['tags']).to be_an(Array)
p['tags'].each do |t|
expect(t).to include('name', 'category', 'has_wiki')
end
end
end end


it "returns empty posts when nothing matches" do it "returns empty posts when nothing matches" do
@@ -104,7 +112,7 @@ RSpec.describe 'Posts API', type: :request do


# show は build_tag_tree_for を使うので、tags はツリー形式(children 付き) # show は build_tag_tree_for を使うので、tags はツリー形式(children 付き)
node = json['tags'][0] node = json['tags'][0]
expect(node).to include('id', 'name', 'category', 'post_count', 'children')
expect(node).to include('id', 'name', 'category', 'post_count', 'children', 'has_wiki')
expect(node['name']).to eq('spec_tag') expect(node['name']).to eq('spec_tag')


expect(json).to have_key('related') expect(json).to have_key('related')


+ 10
- 2
frontend/src/components/TagLink.tsx View File

@@ -32,7 +32,15 @@ export default (({ tag,
...props }: Props) => { ...props }: Props) => {
const [havingWiki, setHavingWiki] = useState (true) const [havingWiki, setHavingWiki] = useState (true)


const wikiExists = async (tagName: string) => {
const wikiExists = async (tag: Tag) => {
if ('hasWiki' in tag)
{
setHavingWiki (tag.hasWiki)
return
}

const tagName = (tag as Tag).name

try try
{ {
await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`) await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`)
@@ -48,7 +56,7 @@ export default (({ tag,
if (!(linkFlg) || !(withWiki)) if (!(linkFlg) || !(withWiki))
return return


wikiExists (tag.name)
wikiExists (tag)
}, [tag.name, linkFlg, withWiki]) }, [tag.name, linkFlg, withWiki])


const spanClass = cn ( const spanClass = cn (


+ 1
- 0
frontend/src/types.ts View File

@@ -48,6 +48,7 @@ export type Tag = {
name: string name: string
category: Category category: Category
postCount: number postCount: number
hasWiki: boolean
children?: Tag[] } children?: Tag[] }


export type User = { export type User = {


Loading…
Cancel
Save