has_many with :uniq not working for me

Hi all,

I have a relationship (no really!)

class RiskMatrix < ActiveRecord::Base
has_many :severities, :order => :position, :uniq => true
end

class RiskFactor < ActiveRecord::Base

belongs_to :risk_matrix

validates_presence_of :descriptor, :example
validates_uniqueness_of :descriptor, :example, :scope=> :risk_matrix_id

end

class Severity < RiskFactor

acts_as_list :scope => :risk_matrix
end

I don’t want any duplicates for a given risk matrix of a risk factor so I wrote a couple of tests. Both of them fail but I’m not sure why.

def test_no severity should be duplicated for a risk_matrix

sev = @rm.severities.find(:first ) # @rm is a risk matrix set during setup
@rm.severities << sev
assert_equal 1, @rm.severities.select{ |s| s == sev }.size

end

def test_descriptor should be uniq for a given risk matrix

@sev = Severity.find(:first )
@rm = @sev.risk_matrix
@rm.severities << @sev.dup
assert_equal 1, @rm.severities.select{|s| s.descriptor == @sev.descriptor }.size

end

The uniq option doesn’t seem to be doing anything. Am I using it incorrectly?

Thanx to anyone who can help me.

Cheers
Daniel

Hi all… Sorry to bump but this is driving me nuts.

Right on the money as usual. Thanx

My test ended up as follows:

specify “no severity should be duplicated for a risk_matrix” do
sev = @rm.severities.find(:first )
@rm.severities << sev
@rm.save
@rm.severities.reset
assert_equal 1, @
rm.severities.select{ |s| s == sev }.size
end

And
specify “descriptor should be uniq for a given risk matrix” do
@sev = Severity.find(:first )
@rm = @sev.risk_matrix
sev = Severity.new
( :descriptor => @sev.descriptor, :example => “this is some example”, :risk_matrix => @rm )
assert !sev.valid?
end

I think it must’ve been a bit late for the second one last night because that seems really easy now.

The first test though seems to smell a bit. I don’t think I would remember to

@rm.severities << sev

@rm.save

@rm.severities.reset

everywhere in my code when I want to add a severity to the matrix.

Prior to this snippet, the RiskMatrix in @rm is read from the DB.

I also thought that the << would automagically save the association. Do I need to do this everytime I want to add to the collecion?

Cheers
Daniel

For posterities sake, the test

specify “no severity should be duplicated for a risk_matrix” do
sev = @rm.severities.find(:first )
@rm.severities
<< sev
@rm.save
@rm.severities.reset
assert_equal 1, @
rm.severities.select{ |s| s == sev }.size
end

is a pain because I’ve selected the severities into an array. That’s why the severities need to be reset first. Instead, by using count on the association collection

specify “no severity should be duplicated for a risk_matrix” do
sev = @rm.severities.find(:first )
initial_severities = @rm.severities.count
@rm.severities << sev
@rm.save

assert_equal initial_severities, @rm.severities.count

end

works as expected.