Hey guys, I''ve been practicing TDD on my rails apps for a while now, and I''m constantly plagued by factory girl and its association support. It really irks me to see that a test failed because object A calls a.association ... on object B which calls b.association on ... which tries to instantiate a duplicate of object C, which already exists, and so its uniqueness validations fail, causing the whole chain of the test to explode. I''ve been chasing this damn chicken-or-the-egg problem for a while, but ultimately I''m wondering if it''s time to scrap factory girl and look at something else. Problem is, most of the other alternatives, Machinist being the primary one I know about, don''t appear to have been updated to work with Rails 3 (and there''s no way I''m going back to 2.x!). So, that said, can you recommend some relatively recent and up-to-date fixture replacement frameworks for Rails, or is factory_girl really about my only option? Thanks :) -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 27 December 2010 14:07, Phoenix Rising <polarisrising-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hey guys, > > I''ve been practicing TDD on my rails apps for a while now, and I''m > constantly plagued by factory girl and its association support. It > really irks me to see that a test failed because object A calls > a.association ... on object B which calls b.association on ... which > tries to instantiate a duplicate of object C, which already exists, > and so its uniqueness validations fail, causing the whole chain of the > test to explode. > > I''ve been chasing this damn chicken-or-the-egg problem for a while, > but ultimately I''m wondering if it''s time to scrap factory girl and > look at something else. Problem is, most of the other alternatives, > Machinist being the primary one I know about, don''t appear to have > been updated to work with Rails 3 (and there''s no way I''m going back > to 2.x!). > > So, that said, can you recommend some relatively recent and up-to-date > fixture replacement frameworks for Rails, or is factory_girl really > about my only option?I cannot say that I understand the problem you are describing, but Machinist is working fine for me on Rails 3. Colin -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Phoenix Rising wrote in post #970881:> Hey guys, > > I''ve been practicing TDD on my rails apps for a while now, and I''m > constantly plagued by factory girl and its association support. It > really irks me to see that a test failed because object A calls > a.association ... on object B which calls b.association on ... which > tries to instantiate a duplicate of object C, which already exists, > and so its uniqueness validations fail, causing the whole chain of the > test to explode.Then your factories are set up incorrectly. This should not be happening. Let''s see some factory code that is giving you trouble.> > I''ve been chasing this damn chicken-or-the-egg problem for a while, > but ultimately I''m wondering if it''s time to scrap factory girl and > look at something else.Doesn''t sound like a Factory Girl problem. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org Sent from my iPhone -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thank you for the reply, Colin. I should have been more descriptive, so let me elaborate: Say I have the following models and factories: # models class Game < ActiveRecord::Base validates :name, :presence => true, :uniqueness => true validates :url, :presence => true, :uniqueness => true end class Server < ActiveRecord::Base belongs_to :game validates :name, :presence => true validates :game, :presence => true end class Character < ActiveRecord::Base belongs_to :server # now we can chain character.server.game validates :name, :presence => true end # test/factories.rb Factory.define :game do |g| g.name "Foo" g.url "www.example.com" end Factory.define :server do |s| s.name "Bar" s.game { |x| x.association(:game) } end Factory.define :character do |c| c.name "Blah" c.server { |x| x.association(:server) } end Now, let''s say I want to call Factory(:character). It all gets set up and returned properly as it should. But let''s say I have the following in my factories thereafter: Factory.define :character2 do |c| c.name "Bleh" c.server { |x| x.association(:server) } end Logically, I''d expect factory_girl to try to create the :server object, and if it fails, look for it in the database and set the assignment of that association to what comes out of the DB if something already exists. But it doesn''t do that. Instead, FG will cause an error in tests (not a failure, an actual error) that will say that the name and url are already taken. After shaking my fists in the air and pounding my head on the desk, I reply, "YES, I KNOW they''re taken, that''s because I want the association on an EXISTING OBJECT!" Am I just plain doing it wrong here? Any input you have would be appreciated. Thank you! On Dec 27, 7:16 am, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> On 27 December 2010 14:07, Phoenix Rising <polarisris...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > > > > > Hey guys, > > > I''ve been practicing TDD on my rails apps for a while now, and I''m > > constantly plagued by factory girl and its association support. It > > really irks me to see that a test failed because object A calls > > a.association ... on object B which calls b.association on ... which > > tries to instantiate a duplicate of object C, which already exists, > > and so its uniqueness validations fail, causing the whole chain of the > > test to explode. > > > I''ve been chasing this damn chicken-or-the-egg problem for a while, > > but ultimately I''m wondering if it''s time to scrap factory girl and > > look at something else. Problem is, most of the other alternatives, > > Machinist being the primary one I know about, don''t appear to have > > been updated to work with Rails 3 (and there''s no way I''m going back > > to 2.x!). > > > So, that said, can you recommend some relatively recent and up-to-date > > fixture replacement frameworks for Rails, or is factory_girl really > > about my only option? > > I cannot say that I understand the problem you are describing, but > Machinist is working fine for me on Rails 3. > > Colin-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 27 December 2010 14:40, Phoenix Rising <polarisrising-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thank you for the reply, Colin. I should have been more descriptive, > so let me elaborate: > > Say I have the following models and factories: > > # models > class Game < ActiveRecord::Base > validates :name, :presence => true, :uniqueness => true > validates :url, :presence => true, :uniqueness => true > end > > class Server < ActiveRecord::Base > belongs_to :game > validates :name, :presence => true > validates :game, :presence => true > end > > class Character < ActiveRecord::Base > belongs_to :server # now we can chain character.server.game > validates :name, :presence => true > end > > # test/factories.rb > Factory.define :game do |g| > g.name "Foo" > g.url "www.example.com" > end > > Factory.define :server do |s| > s.name "Bar" > s.game { |x| x.association(:game) } > end > > Factory.define :character do |c| > c.name "Blah" > c.server { |x| x.association(:server) } > end > > Now, let''s say I want to call Factory(:character). It all gets set up > and returned properly as it should. But let''s say I have the > following in my factories thereafter: > > Factory.define :character2 do |c| > c.name "Bleh" > c.server { |x| x.association(:server) } > end > > Logically, I''d expect factory_girl to try to create the :server > object, and if it fails, look for it in the database and set the > assignment of that association to what comes out of the DB if > something already exists. But it doesn''t do that. Instead, FG will > cause an error in tests (not a failure, an actual error) that will say > that the name and url are already taken. After shaking my fists in > the air and pounding my head on the desk, I reply, "YES, I KNOW > they''re taken, that''s because I want the association on an EXISTING > OBJECT!" > > Am I just plain doing it wrong here? Any input you have would be > appreciated. Thank you! >Yes, I think you are. Have a look at the Faker gem for generating unique patterns. Colin -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Phoenix Rising wrote in post #970888:> Thank you for the reply, Colin. I should have been more descriptive, > so let me elaborate: > > Say I have the following models and factories: > > # models > class Game < ActiveRecord::Base > validates :name, :presence => true, :uniqueness => true > validates :url, :presence => true, :uniqueness => true > end > > class Server < ActiveRecord::Base > belongs_to :game > validates :name, :presence => true > validates :game, :presence => true > endServer belongs_to Game? Really? Are you sure? If so, why isn''t there a corresponding association on Game? What are you trying to model here?> > class Character < ActiveRecord::Base > belongs_to :server # now we can chain character.server.game > validates :name, :presence => true > end > > # test/factories.rb > Factory.define :game do |g| > g.name "Foo" > g.url "www.example.com" > end > > Factory.define :server do |s| > s.name "Bar" > s.game { |x| x.association(:game) } > end > > Factory.define :character do |c| > c.name "Blah" > c.server { |x| x.association(:server) } > endWhat''s with all the constant data? Use Faker and/or sequences to generate unique values.> > Now, let''s say I want to call Factory(:character). It all gets set up > and returned properly as it should. But let''s say I have the > following in my factories thereafter: > > Factory.define :character2 do |c| > c.name "Bleh" > c.server { |x| x.association(:server) } > endAgain, I worry about :character2. Looks like you''re trying to predefine every record you need in your factory files -- that is, use them like fixtures -- which is not how factories are supposed to work. The reason you can define multiple factories for one class is so you can set up several default configurations (say, ordinary user and admin user), not so you can define every record in advance.> > Logically, I''d expect factory_girl to try to create the :server > object, and if it fails, look for it in the database and set the > assignment of that association to what comes out of the DB if > something already exists. But it doesn''t do that.No, it doesn''t. association *always* creates a new record. Of course, you can override that by doing Factory :character, :server => @server. But this is not like fixtures, where it retrieves an existing named fixture. Nor would you want it to be; it would make factories less flexible. You can also use AR model methods to find the existing association record you want.> Instead, FG will > cause an error in tests (not a failure, an actual error) that will say > that the name and url are already taken. After shaking my fists in > the air and pounding my head on the desk, I reply, "YES, I KNOW > they''re taken, that''s because I want the association on an EXISTING > OBJECT!"...which is not what the association method does. Find the object and use it explicitly.> > Am I just plain doing it wrong here? Any input you have would be > appreciated. Thank you!Yes, you are doing it wrong. You''re trying to use factories like fixtures, and (possibly as a result) you''re misunderstanding the semantics of the association method. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org Sent from my iPhone -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.