掲示板実装
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled

This commit is contained in:
2026-02-19 22:30:59 +09:00
parent f25fd6f802
commit bb9ec2df1d
38 changed files with 1711 additions and 13 deletions

61
app/models/board.rb Normal file
View File

@@ -0,0 +1,61 @@
class Board < ApplicationRecord
belongs_to :game
belongs_to :creator, class_name: "Participant",
foreign_key: "created_by_participant_id", optional: true
has_many :board_memberships, dependent: :destroy
has_many :active_memberships, -> { where(left_at: nil) },
class_name: "BoardMembership"
has_many :participants, through: :board_memberships
has_many :board_posts, dependent: :destroy
has_many :board_proposals, dependent: :destroy
enum :board_type, { global: "global", negotiation: "negotiation" }
validate :no_duplicate_member_combination, if: :negotiation?
# メンバーかどうか判定退出済みはfalse
def member?(participant)
return false unless participant
board_memberships.exists?(participant_id: participant.id, left_at: nil)
end
# 履歴モードかどうかゲーム終了後は常にtrue
def history_mode?
game.status == "finished"
end
# 指定した参加者の未読件数を取得
def unread_count_for(participant)
return 0 unless participant
membership = board_memberships.find_by(participant_id: participant.id)
# メンバーでない、または退出済みの場合は未読なしとするあるいは全件とするか要検討だが、一旦0
return 0 unless membership && membership.active?
last_id = membership.last_read_post_id || 0
board_posts.where("id > ?", last_id).count
end
private
def no_duplicate_member_combination
# 新規作成時のみチェック(更新時はメンバー変動があるため別途考慮が必要だが、今回は作成時のみ想定)
# ただしメンバー追加時にもチェックが必要になる可能性があるため、Boardモデルのバリデーションとして定義
# 比較対象のメンバーIDリストソート済み
current_member_ids = board_memberships.map(&:participant_id).sort
# 同じゲーム内の他の交渉用掲示板を検索
game.boards.negotiation.where.not(id: id).each do |other_board|
# 退出者を含めた全メンバー構成で比較するか、アクティブメンバーのみで比較するか
# 仕様書「同じメンバー構成の掲示板は作成できない」
# ここでは「現在参加しているメンバー」の構成が重複しないようにする
other_member_ids = other_board.board_memberships.where(left_at: nil).pluck(:participant_id).sort
if other_member_ids == current_member_ids
errors.add(:base, "同じメンバー構成の掲示板がすでに存在します")
return
end
end
end
end