みなしエンティティをリソースとして扱う
code:app/models/post.rb
class Post < ApplicationRecord
def cancel(at: Time.zone.now)
self.cancelled_at = at
save
end
def cancelled?
!cancelled_at.nil?
end
def display_body
cancelled? ? 'This post is deleted.' : body
end
end
実際は削除イベントのみなしエンティティを posts テーブルに埋め込んでいるだけなのでこういう感じの実装でもいいのかなあという感じ
code:app/models/post.rb
class Post < ApplicationRecord
def cancellation
Post::Cancellation.new(self)
end
def display_body
cancellation.persisted? ? 'This post is deleted.' : body
end
end
Post::Cancellation = Struct.new(:post) do
delegate :errors, to: :post
def create
post.cancelled_at = Time.zone.now
save
end
def destroy
post.cancelled_at = nil
save
end
def persisted?
!post.cancelled_at.nil?
end
end
コントローラはこんな感じになるはず
code:app/controllers/post_cancellations_controller.rb
class PostCancellationsController < ApplicationController
before_action :set_board
before_action :set_post
before_action :set_post_cancellation
# POST /boards/:board_id/posts/1/cancellation
# POST /boards/:board_id/posts/1/cancellation.json
def create
respond_to do |format|
if @cancellation.create
format.html { redirect_to @board, notice: 'PostCancellation was successfully created.' }
format.json { render :show, status: :created, location: @board }
else
format.html { render 'boards/show' }
format.json { render json: @cancellation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /boards/:board_id/posts/1/cancellation
# DELETE /boards/:board_id/posts/1/cancellation.json
def destroy
@cancellation.destroy
respond_to do |format|
format.html { redirect_to @board, notice: 'PostCancellation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_board
end
def set_post
@post = @board.posts.find(params:post_id) end
def set_post_cancellation
@cancellation = @post.cancellation
end
end
これも