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
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Hi all.. Sorry to bump but this is driving me nuts. On 12/6/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > 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 > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel ----- wrote:> 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?The :uniq option is really only useful for has_many :through associations. How else would you get the same record in a has_many association more than once? I don''t fully understand your modelling problem, but I''m guessing if you are worried about dupes you might be wanting to use a many-to-many mapping, like a has_many :through. If not, and you just have a has_many, you shouldn''t need to use :uniq. What''s going on in your tests is that you are adding the sev object to the in-memory collection, then checking to see if it''s there, which it of course is. You haven''t saved anything to the database, or updated the in-memory collection with new content from the database. And since you aren''t saving your model, the validations don''t run, so the validates_uniqueness_of check won''t catch anything. Remember, ActiveRecord is an ORM system, and it only does something useful when you are either reading from or writing to the database. If you want some examples of :uniq with has_many :through, search in my blog for "uniq". And you''re on the right track for the validation, you''ll just need to adjust for the new association. -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/6/06, Josh Susser <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Daniel ----- wrote: > > 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? > > The :uniq option is really only useful for has_many :through > associations. How else would you get the same record in a has_many > association more than once? I don''t fully understand your modelling > problem, but I''m guessing if you are worried about dupes you might be > wanting to use a many-to-many mapping, like a has_many :through. If not, > and you just have a has_many, you shouldn''t need to use :uniq. > > What''s going on in your tests is that you are adding the sev object to > the in-memory collection, then checking to see if it''s there, which it > of course is. You haven''t saved anything to the database, or updated the > in-memory collection with new content from the database. And since you > aren''t saving your model, the validations don''t run, so the > validates_uniqueness_of check won''t catch anything. Remember, > ActiveRecord is an ORM system, and it only does something useful when > you are either reading from or writing to the database. > > If you want some examples of :uniq with has_many :through, search in my > blog for "uniq". And you''re on the right track for the validation, > you''ll just need to adjust for the new association. > > -- > Josh Susser > http://blog.hasmanythrough.comRight 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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/6/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > On 12/6/06, Josh Susser <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > > > > > Daniel ----- wrote: > > > 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? > > > > The :uniq option is really only useful for has_many :through > > associations. How else would you get the same record in a has_many > > association more than once? I don''t fully understand your modelling > > problem, but I''m guessing if you are worried about dupes you might be > > wanting to use a many-to-many mapping, like a has_many :through. If not, > > and you just have a has_many, you shouldn''t need to use :uniq. > > > > What''s going on in your tests is that you are adding the sev object to > > the in-memory collection, then checking to see if it''s there, which it > > of course is. You haven''t saved anything to the database, or updated the > > in-memory collection with new content from the database. And since you > > aren''t saving your model, the validations don''t run, so the > > validates_uniqueness_of check won''t catch anything. Remember, > > ActiveRecord is an ORM system, and it only does something useful when > > you are either reading from or writing to the database. > > > > If you want some examples of :uniq with has_many :through, search in my > > blog for "uniq". And you''re on the right track for the validation, > > you''ll just need to adjust for the new association. > > > > -- > > Josh Susser > > http://blog.hasmanythrough.com > > > 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. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---