views:

223

answers:

1

I have a model, Game, which has_many :piles. In fact, I know that each Game has exactly 4 piles, each of which has a different (at the scope of the Game) contents. My web-form for creating a Game allows the user to pick the four contents (as c_type_#). I'm therefore able to populate the Piles at creation of the Game. However, I can't figure out how to ensure that I have precisely 4 unique Piles. My models look like this:

class Game < ActiveRecord::Base
  has_many :piles

  def after_create
    1.upto(4) do |num|
      piles.create("contents" => "c_type_#{num}")
    end
  end
end

class Pile < ActiveRecord::Base
  belongs_to :game
  validates_uniqueness_of :contents, :scope => "game_id"
end

... and my migration to add Piles looks like:

class CreatePiles < ActiveRecord::Migration
  def self.up
    create_table :piles do |t|
      t.integer :game_id
      t.string :contents
    end

    add_index :piles, [:game_id, :contents], :unique => true
  end

  def self.down
    drop_table :piles
  end
end

...but all this means is that the non-unique Piles aren't added to the database, silently; and the parent Game ends up with fewer than 4 piles.

I have currently worked around this by having Game validate :unique_pile_contents, :on => :create, where unique_pile_contents verifies that the length of a uniq'd array of the c_type_# values is 4 - but this feels very kludgy. Is there a better way?

+1  A: 

I've managed to solve this as part of another problem I was tackling. See http://stackoverflow.com/questions/2110857/2116746#2116746 for the answer (and a slightly simpler example in the question).

Chris