Hi all, I''ve got some tables with fixed amounts of data in them (a "states" table, for example). For tables like this I can easily put *all* of the data in the fixture. For general futzing purposes, and for those times I want to reload a database from scratch outside of testing (for whatever reason), what''s the best approach? I thought perhaps ActiveRecord::Base had something built in to allow me to load a .yml file, but I don''t see it. I realize I could redefine initialize in ActiveRecord::Base to do special handling if the argument was a string ending in ".yml" or an IO object, but I thought I would ask here first. Regards, Dan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Nov 10, 2005, at 1:17 PM, Berger, Daniel wrote:> I''ve got some tables with fixed amounts of data in them (a "states" > table, for example). For tables like this I can easily put *all* > of the > data in the fixture. > > For general futzing purposes, and for those times I want to reload a > database from scratch outside of testing (for whatever reason), what''s > the best approach? I thought perhaps ActiveRecord::Base had something > built in to allow me to load a .yml file, but I don''t see it.Check out the :load_fixtures Rake task.> I realize I could redefine initialize in ActiveRecord::Base to do > special handling if the argument was a string ending in ".yml" or > an IO > object, but I thought I would ask here first.Interesting idea... jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDc70WAQHALep9HFYRAoB/AJ9fHUHrFtcz6F0e1d+gDZ2GENd+2gCgq9zv 5cr4X7Vez40QNF4/QY6gshY=wrc6 -----END PGP SIGNATURE-----
You can probably use "rake load_fixtures" (run rake --tasks for description) and it will load fixtures into current database (Whatever your env is set to). However if you have a specific order that you need to load fixtures due to foreign key constraints etc then you can use something like the following. I store this in a file lib\tasks\db.rake annd it deletes the data and reloads the data in the proper order to ensure no constraints are violated. desc "Reset Database data to that in fixtures" task :reset_db_data => :environment do require ''active_record/fixtures'' ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) metadata_fixtures = [ :icons, :severities, :types, :statuses, :resolutions ] project_fixtures = [ :users, :projects, :components, :versions ] issue_fixtures = [ :issues, :comments, :issues_affects_versions, :issues_fixfor_versions, :issues_components ] fixtures = (metadata_fixtures + project_fixtures + issue_fixtures).collect {|x| x.to_s } Fixtures.create_fixtures(''test/fixtures'', fixtures) end HTH, Peter Donald
Peter Donald wrote:> You can probably use "rake load_fixtures" (run rake --tasks for > description) and it will load fixtures into current database (Whatever > your env is set to).Ah, thanks Peter (and Jeremy).> However if you have a specific order that you > need to load fixtures due to foreign key constraints etc then you can > use something like the following. I store this in a file > lib\tasks\db.rake annd it deletes the data and reloads the data in the > proper order to ensure no constraints are violated. > > desc "Reset Database data to that in fixtures" > task :reset_db_data => :environment do > require ''active_record/fixtures'' > ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) > > metadata_fixtures = [ :icons, :severities, :types, :statuses, :resolutions ] > project_fixtures = [ :users, :projects, :components, :versions ] > issue_fixtures = [ :issues, :comments, :issues_affects_versions, > :issues_fixfor_versions, :issues_components ] > fixtures = (metadata_fixtures + project_fixtures + > issue_fixtures).collect {|x| x.to_s } > Fixtures.create_fixtures(''test/fixtures'', fixtures) > end > > HTH, > > Peter DonaldYes, it does help, thanks. However, for those of you tinkering with ActiveRecord in standalone fashion, a small diff (against 1.13.0) is below: --- base.orig Thu Nov 10 14:54:48 2005 +++ base.rb Thu Nov 10 15:39:27 2005 @@ -457,14 +457,19 @@ # Creates an object, instantly saves it as a record (if the validation permits it), and returns it. If the save # fails under validations, the unsaved object is still returned. def create(attributes = nil) - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr) } - else - attributes.reverse_merge!(scope(:create)) if scoped?(:create) + case attributes + when Array + attributes.collect { |attr| create(attr) } + when String + YAML.load(File.open(attributes)).values.collect{ |attr| create(attr) } + when IO + YAML.load(attributes).values.collect{ |attr| create(attr) } + else + attributes.reverse_merge!(scope(:create)) if scoped?(:create) - object = new(attributes) - object.save - object + object = new(attributes) + object.save + object end end I also realized that ActiveRecord::Base.new does *not* accept an array of hashes in the same way ActiveRecord::Base.create does. Is this on purpose? Regards, Dan
On 11/11/05, Daniel Berger <Daniel.Berger-6vC2hAQLr78AvxtiuMwx3w@public.gmane.org> wrote:> I also realized that ActiveRecord::Base.new does *not* accept an array of > hashes in the same way ActiveRecord::Base.create does. Is this on purpose?Thats the documented behaviour so it is intentional but it kinda surprised me.
Peter Donald wrote:> You can probably use "rake load_fixtures" (run rake --tasks for > description) and it will load fixtures into current database (Whatever > your env is set to). However if you have a specific order that you > need to load fixtures due to foreign key constraints etc then you can > use something like the following. I store this in a file > lib\tasks\db.rake annd it deletes the data and reloads the data in the > proper order to ensure no constraints are violated. > > desc "Reset Database data to that in fixtures" > task :reset_db_data => :environment do > require ''active_record/fixtures'' > ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) > > metadata_fixtures = [ :icons, :severities, :types, :statuses, :resolutions ] > project_fixtures = [ :users, :projects, :components, :versions ] > issue_fixtures = [ :issues, :comments, :issues_affects_versions, > :issues_fixfor_versions, :issues_components ] > fixtures = (metadata_fixtures + project_fixtures + > issue_fixtures).collect {|x| x.to_s } > Fixtures.create_fixtures(''test/fixtures'', fixtures) > end > > HTH, > > Peter DonaldInterestingly, it looks like there''s no corresponding Fixtures.delete_fixtures method. It''s all or nothing with Fixtures.delete_existing_fixtures. Any chance of adding a Fixtures.delete_fixtures method so that I can delete specific fixtures only? Regards, Dan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Nov 11, 2005, at 12:26 PM, Daniel Berger wrote:> Interestingly, it looks like there''s no corresponding > Fixtures.delete_fixtures method. It''s all or nothing with > Fixtures.delete_existing_fixtures. > > Any chance of adding a Fixtures.delete_fixtures method so that I > can delete specific fixtures only?Certainly -- please post an enhancement at http://dev.rubyonrails.com/ newticket Of course, for most speedy addition, include a patch :) jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDdQYtAQHALep9HFYRAjwiAKDFgZElOlCWs8H5HwpJOm8DwJ6LMwCgk6Js gykwcfkTboT10jz6gHA2Bfw=pMGV -----END PGP SIGNATURE-----