62 lines
2.6 KiB
Ruby
62 lines
2.6 KiB
Ruby
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
|