This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
class MaterialsController < ApplicationController
|
||||
def index
|
||||
page = (params[:page].presence || 1).to_i
|
||||
limit = (params[:limit].presence || 20).to_i
|
||||
|
||||
page = 1 if page < 1
|
||||
limit = 1 if limit < 1
|
||||
|
||||
offset = (page - 1) * limit
|
||||
|
||||
tag_id = params[:tag_id].presence
|
||||
parent_id = params[:parent_id].presence
|
||||
|
||||
q = Material.includes(:tag, :created_by_user).with_attached_file
|
||||
q = q.where(tag_id:) if tag_id
|
||||
q = q.where(parent_id:) if parent_id
|
||||
|
||||
count = q.count
|
||||
materials = q.order(created_at: :desc, id: :desc).limit(limit).offset(offset)
|
||||
|
||||
render json: { materials: materials.map { |m| material_json(m) }, count: count }
|
||||
end
|
||||
|
||||
def show
|
||||
material = Material.includes(:tag, :created_by_user).with_attached_file.find_by(id: params[:id])
|
||||
return head :not_found unless material
|
||||
|
||||
render json: material_json(material)
|
||||
end
|
||||
|
||||
def create
|
||||
return head :unauthorized unless current_user
|
||||
return head :forbidden unless current_user.gte_member?
|
||||
|
||||
file = params[:file]
|
||||
return head :bad_request if file.blank?
|
||||
|
||||
material = Material.new(
|
||||
url: params[:url].presence,
|
||||
parent_id: params[:parent_id].presence,
|
||||
tag_id: params[:tag_id].presence,
|
||||
created_by_user: current_user)
|
||||
material.file.attach(file)
|
||||
|
||||
if material.save
|
||||
render json: material_json(material), status: :created
|
||||
else
|
||||
render json: { errors: material.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
return head :unauthorized unless current_user
|
||||
return head :forbidden unless current_user.gte_member?
|
||||
|
||||
material = Material.with_attached_file.find_by(id: params[:id])
|
||||
return head :not_found unless material
|
||||
|
||||
material.assign_attributes(
|
||||
url: params[:url].presence,
|
||||
parent_id: params[:parent_id].presence,
|
||||
tag_id: params[:tag_id].presence
|
||||
)
|
||||
material.file.attach(params[:file]) if params[:file].present?
|
||||
|
||||
if material.save
|
||||
render json: material_json(material)
|
||||
else
|
||||
render json: { errors: material.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
return head :unauthorized unless current_user
|
||||
return head :forbidden unless current_user.gte_member?
|
||||
|
||||
material = Material.find_by(id: params[:id])
|
||||
return head :not_found unless material
|
||||
|
||||
material.discard
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def material_json(material)
|
||||
MaterialRepr.base(material).merge(
|
||||
'filename' => material.file.attached? ? material.file.filename.to_s : nil,
|
||||
'byte_size' => material.file.attached? ? material.file.byte_size : nil,
|
||||
'content_type' => material.file.attached? ? material.file.content_type : nil,
|
||||
'url' => material.file.attached? ? url_for(material.file) : nil
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
class Material < ApplicationRecord
|
||||
include MyDiscard
|
||||
|
||||
default_scope -> { kept }
|
||||
|
||||
belongs_to :parent, class_name: 'Material', optional: true
|
||||
has_many :children, class_name: 'Material', foreign_key: :parent_id, dependent: :nullify
|
||||
|
||||
belongs_to :tag, optional: true
|
||||
belongs_to :created_by_user, class_name: 'User', optional: true
|
||||
belongs_to :updated_by_user, class_name: 'User', optional: true
|
||||
|
||||
has_one_attached :file, dependent: :purge
|
||||
|
||||
validate :file_must_be_attached
|
||||
validate :tag_must_be_material_category
|
||||
|
||||
private
|
||||
|
||||
def file_must_be_attached
|
||||
return if url.present? || file.attached?
|
||||
|
||||
errors.add(:url, 'URL かファイルのどちらかは必須です.')
|
||||
end
|
||||
|
||||
def tag_must_be_material_category
|
||||
return if tag.blank? || tag.material?
|
||||
|
||||
errors.add(:tag, '素材カテゴリのタグを指定してください.')
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
|
||||
module MaterialRepr
|
||||
BASE = { only: [:id, :url, :parent_id, :created_at, :updated_at],
|
||||
include: { created_by_user: UserRepr::BASE, tag: TagRepr::BASE } }.freeze
|
||||
|
||||
module_function
|
||||
|
||||
def base(material)
|
||||
material.as_json(BASE)
|
||||
end
|
||||
|
||||
def many(materials)
|
||||
materials.map { |m| base(m) }
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user