[英]How should I define multiple relationships between the same two models in Rails 5
I have two models: 我有两个模型:
A Game
that keeps track of the game state in a card game. 一个Game
一个跟踪游戏状态的一个纸牌游戏。
A Deck
that manages how cards are stored, shuffled, dealt, etc. 一个Deck
管理卡的存储方式,洗牌,处理,等等。
The Game
has many different Decks
that it has to keep track of at once. Game
有许多不同的Decks
,必须立即跟踪。 For example, two separate different draw decks and a discard deck. 例如,两个单独的不同的绘图平台和一个废弃平台。
I'm a little stumped on how I should define these relationships. 我对如何定义这些关系感到有些困惑。 Ideally, I would have Game.draw_type_a Game.draw_type_b and Game.discard that I could work with, and they would each point to a single Deck
. 理想情况下,我可以使用Game.draw_type_a Game.draw_type_b和Game.discard,并且它们每个都指向一个Deck
。 I've experimented with has_one :through
relationships and traditional one-to-one relationships with defined foreign_keys and classes, but I haven't been able to get this working. 我已经尝试过has_one :through
关系以及已定义的foreign_keys和class的传统一对一关系,但是我无法使它正常工作。
I'd really like to keep all the decks as a single model, since there is so much overlap in how they behave. 我真的很想将所有卡座保持为单个模型,因为它们的行为有很多重叠之处。 How should I define the relationships between the three types of deck in the Game
and the Deck
model. 我应该如何定义的三种甲板之间的关系, Game
和Deck
模型。 What should the migrations look like to implement them? 实施迁移应采用什么样的方式?
I've done something similar in my Adj game . 我在Adj游戏中做了类似的事情。 This is what I would do: 这就是我要做的:
class Game < ApplicationRecord
has_many :decks
has_one :discard_deck, -> { where(deck_type: :discard) }, foreign_key: :game_id, class_name: 'Deck'
has_one :draw_deck, -> { where(deck_type: :draw) }, foreign_key: :game_id, class_name: 'Deck'
# example attributes:
# is_finished:boolean(default: false)
def start
# populate the decks
draw_deck.create!
discard_deck.create!
# populate random cards to be a draw_deck
total_draw_deck_cards = 50
# pick 50 random cards. `RANDOM()` is for Postgresql; else check online
random_cards = Card.order('RANDOM()').limit(total_draw_deck_cards)
random_cards.each do |random_card|
draw_deck.deck_cards.create!(card: random_card)
end
end
def finish
update!(is_finished: true)
end
# `deck` can be any deck_type. Add conditions here if you must for each different deck_type
def draw_from(deck)
# or if you have multiple players:
# def draw_from(deck, player)
deck_card = deck.deck_cards.first
# then do something with this deck_card that you just drawed
# i.e. you might want to put this into a "Hand" (Player), so you'll need a separate PlayerCard model
# PlayerCard.create!(card: deck_card.card)
# or if you have multiple players:
# PlayerCard.create!(card: deck_card.card, player: player)
# then lastly remove this deck_card as you've already put it in your hand
deck_card.destroy
end
end
class Deck < ApplicationRecord
enum deck_type: { draw: 0, discard: 1 }
belongs_to :game
has_many :deck_cards, -> { order(created_at: :desc) }
has_many :cards, through: :deck_cards
# example attributes:
# deck_type:integer
end
class DeckCard < ApplicationRecord
belongs_to :deck
belongs_to :card
# example attributes:
# is_faced_down:boolean(default: true)
end
class Card < ApplicationRecord
enum card_type: { monster: 0, magic: 1, trap: 2 }
has_many :deck_cards
has_many :decks, through: :deck_cards
# example attributes:
# name:string
# image:string
# card_type:integer
end
I would use a three table solution, namely: games, decks, game_decks(?). 我将使用三表解决方案,即:游戏,套牌,game_decks(?)。
Games has many game_decks. 游戏中有很多game_decks。 GameDecks have a game_id, deck_id, and deck_type (draw_type_a, draw_type_b, etc.), so it belongs to games and belongs to decks Decks has many GameDecks. GameDecks具有game_id,deck_id和deck_type(draw_type_a,draw_type_b等),因此它属于游戏,并且属于Deck。Decks具有许多GameDecks。
Additionally, Games has many Decks through GameDecks, and Decks has many Games through GameDecks. 此外,Games通过GameDecks具有许多Decks,而Decks通过GameDecks具有许多Game。
This allows you to do things like game.decks
to retreive all game decks and game.decks.where(deck_type: :draw_type_a)
for all of the game's draw_type_a decks (this can be further refined with scopes). 这样,您就可game.decks
游戏的所有game.decks.where(deck_type: :draw_type_a)
牌组执行game.decks.where(deck_type: :draw_type_a)
类的game.decks
来恢复所有游戏牌组和game.decks.where(deck_type: :draw_type_a)
(可以使用范围进一步完善)。
As a side note, I would use a rails enum for the GameDecks.deck_type field. 附带说明一下,我将在GameDecks.deck_type字段中使用rails枚举。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.