2

ゲームのようなRailsアプリをセットアップしようとしています。アプリにはユーザーがいて、それぞれが作成できるポーンを持っています。ユーザーは、他のユーザーと自分が作成したポーンを検索し、必要に応じて自分のポーンの 1 つを使用して別のユーザーに挑戦できます。チャレンジされたユーザーは、チャレンジを受け入れる/辞退することができます。

現在、ユーザーのポーンを追加/削除できます。モデルは次のようになります。

class User < ActiveRecord::Base
  has_many :pawns, dependent: :destroy

class Pawn < ActiveRecord::Base
  belongs_to :user

ここで、User1 が User2 によって作成された Pawn に挑戦したい場合、User2 の Pawn のリストを見て、必要な Pawn の [Challenge] ボタンをクリックします。次に、ユーザー 1 は自分のポーンの 1 つを選択してチャレンジに使用し、[保存] をクリックする必要があります。ここで、User2 はチャレンジを受け入れるか拒否する必要があります。

課題をどのように設定するかについて頭を悩ませています。私の考えでは、各 Pawn は自己参照型の多対多の関係を持ち、まるで友情関係がセットアップされるようになると思います。ただし、チャレンジをユーザーまたはポーンに関連するものと見なす必要があるかどうかはわかりません。

このようなものをモデル化する最良の方法は何ですか?

編集:

これが私が達成しようとしていることの図です。私は間違いなく、ある種の関連付けのセットアップが必要だと思います。結果には、そのチャレンジのポーンの統計 (time_spent、clicks_made など) が保持されます。チャレンジには、勝者などの列もあります。

ここに画像の説明を入力

4

3 に答える 3

3

チャレンジには、ポーンの種類ごとに関連付けが定義されている場合があります。

class Challenge < ActiveRecord::Base
  # attributes :challengee_id, :challenger_id

  belongs_to :challengee, class_name: "Pawn"
  belongs_to :challenger, class_name: "Pawn"

  has_many :results
end

ポーンには、チャレンジの種類ごとに関連付けがあります。

class Pawn < ActiveRecord::Base
  # attributes :user_id

  belongs_to :user

  has_many :results
  has_many :initiated_challenges, class_name: "Challenge", foreign_key: :challenger_id
  has_many :received_challenges, class_name: "Challenge", foreign_key: :challengee_id
end

結果レコードの challenge_id を非正規化しても問題ないでしょう。

class Result < ActiveRecord::Base
  # attributes: pawn_id, challenge_id, :result
  belongs_to :pawn
  belongs_to :challenge
end

ユーザーは、ポーンおよびポーンを介したチャレンジに関連付けることができます。ユーザーに関連付けられた両方のチャレンジ タイプを取得する簡単な方法は、2 つのチャレンジの関連付け (開始および受信) の結果を 1 つのメソッド #challenge に結合することです。

class User < ActiveRecord::Base
  has_many :pawns
  has_many :initiated_challenges, through: :pawns, source: :initiated_challenges
  has_many :received_challenges, through: :pawns, source: :received_challenges

  def challenges
    initiated_challenges + received_challenges
  end
end

このメソッドのパフォーマンスの最適化には、:challengee_user_id および :challenger_user_id... としてチャレンジの user_ids を非正規化するか、ユーザーのチャレンジ ID のリストをキャッシュして、2 つではなく 1 つのクエリを作成することが含まれます。

于 2012-09-23T16:52:15.180 に答える
2

Challengeswith fieldsという別のテーブルを設定できますchallenger_id, challengee_id, status。挑戦者と挑戦者の ID はもちろん、ユーザーではなくポーンを表します。ステータスは を表しchallenge_pending, challenge_on_goingます。明らかにこれを行う方法は他にもありますが、これは 1 つです。

これには、ポーンからポーンへのチャレンジをそれぞれ 1 つに制限できるという追加の利点があります。

ビューコントローラーで

@challenges = Challenge.where("challengee_id IN (?)", Pawn.find_all_by_owner_id(current_user.id).map{|u| u[:id]})
@challenged = Challenge.where("challenger_id IN (?)", Pawn.find_all_by_owner_id(current_user.id).map{|u| u[:id]})

あなたの見解では

<%= @challenges.each do |challenge| %>
  whatever
<% end %>
于 2012-09-16T00:04:17.490 に答える
1
class User < ActiveRecord::Base
    has_many :pawns
end

class Pawn < ActiveRecord::Base
    belongs_to :user

    has_many :challengers, class_name: 'Challenge'
    has_many :challengees, class_name: 'Challenge'

    belongs_to :result
end

class Challenge < ActiveRecord::Base
    belongs_to :challenger, class_name: 'Pawn'
    belongs_to :challengee, class_name: 'Pawn'

    belongs_to :result
end

class Result < ActiveRecord::Base
    has_one :challenge
    has_one :winner, class_name: 'Pawn'
end
于 2012-09-19T22:22:35.333 に答える