2

私はレールにかなり慣れていないので、データベーステーブル間の関係を理解するのに問題があることに気づきました(推測しますか?)。

私の問題は次のとおりです。

メールアドレスを含むユーザーに関する情報を含むユーザーテーブルと、プレイしたプレーヤーを管理したい「ゲーム」を含む別のテーブルがあります。プレーヤーがゲームを送信する場合、ゲームに参加しているユーザーをメール アドレスで指定する必要があります。それらのプレイヤーが本当に存在するかどうかを検証したいと思います。

私のゲームモデル:

class Game < ActiveRecord::Base
  attr_accessible :caster1, :caster2, :faction1, :faction2, :player1, :player2, :points, :won

  before_save { |game| player1 = player1.downcase }
  before_save { |game| player2 = player2.downcase }

  validate :existence_of_both_players

  ...
  (some more validations)
  ...

  private
    def existence_of_both_players
        User.exists?(:email => :player1.downcase) && User.exists?(:email => :player2.downcase)
    end
end

私のテストケースは次のとおりです。

require 'spec_helper'

describe Game do

  before do
    @game = Game.new( player1:  "foobar@example.com",
                      faction1: "Some faction",
                      caster1:  "Some caster",
                      player2:  "bazbaz@example.com",
                      faction2: "Some other faction",
                      caster2:  "Some other caster",
                      points:   35,
                      won:      true)
  end

  ...
  (some other specs)
  ...

  describe "saving a game" do
    let(:player1) { User.create(name:                   "Example1", 
                                email:                  "example1@foo.bar",
                                password:               "foobar",
                                password_confirmation:  "foobar") }
    let(:player2) { User.create(name:                   "Example2", 
                                email:                  "example2@foo.bar",
                                password:               "foobar",
                                password_confirmation:  "foobar") }

    describe "with invalid players" do

      describe "when both players do not exist" do
        before { @game.player1 = @game.player2 = "some_wrong_user@example.com" }
        it { should_not be_valid }
      end

      describe "when player1 does not exist" do
        before { @game.player2 = player2 }
        it { should_not be_valid }
      end

      describe "when player2 does not exist" do
        before { @game.player1 = player1 }
        it { should_not be_valid }
      end
    end

    describe "with valid players" do
      before do 
        @game.player1 = player1
        @game.player2 = player2
      end

      it { should be_valid }
    end
  end
end

(大量のコードで申し訳ありませんが、役立つと思いました)。

私のテストは失敗しています。悲しいことに、私にとってはそうではありません。

Failures:

  1) Game saving a game with invalid players when both players do not exist 
     Failure/Error: it { should_not be_valid }
       expected valid? to return false, got true
     # ./spec/models/game_spec.rb:108:in `block (5 levels) in <top (required)>'
...

なぜこれが機能しないのか、本当にわかりません。Rails book を読み、いくつかのスクリーンキャストを見ましたが、どれも私の問題を適切に説明していません。

これは、stackoverflow に関する私の最初の投稿であるため、この投稿が冗長すぎる場合はお知らせください。前もって感謝します。

4

1 に答える 1

1

カスタム バリデータ メソッドは、errors.add を呼び出してエラーを通知する必要があります。したがって、あなたの場合は次のようになります。

    def existence_of_both_players
      player_one_exists = User.find_by_email :player1.downcase
      player_two_exists = User.find_by_email :player2.downcase
      unless player_one_exists and player_two_exists
          errors.add :game, "both players need to exist"
      end
    end

詳細については、ActiveRecord Validations and Callbacksのガイドを参照してください。

于 2012-09-20T11:45:14.300 に答える