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 -~----------~----~----~----~------~----~------~--~---