Hi all I am indeed a DataMapper newbie and I apologize for that from the start. I started looking it up because I have a job with an intricate maze of legacy databases related to each other and indeed DataMapper seems to fit the bill perfectly. However, since I have many models and many different databases I was trying to remove the duplication and hide the nitty-gritty of connections within a module that could extend DataMapper::Resource and be included in each model a` la DataMapper::Resource. I tried this but it does not work:
------------------------------------------------------------------------ 1 begin 2 require 'ruby-debug' 3 Debugger.start 4 Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings) 5 rescue LoadError 6 # ruby-debug wasn't available so neither can the debugging be 7 end 8 9 require 'dm-core' 10 require 'dm-migrations' 11 12 module DmConnector 13 14 def self.included(base) 15 base.extend ClassMethods 16 end 17 18 module ClassMethods 19 20 @@connections = {} 21 22 def connect_to_db(dbname, context) 23 send(:define_method, :default_repository_name) { context } 24 @@connections[context] = DataMapper.setup(context, dbname) unless @@connections.has_key?(context) 25 DataMapper.auto_upgrade!(context) 26 @@connections[context] 27 end 28 29 DataMapper::Model.append_inclusions self 30 31 end 32 33 end 34 35 DataMapper.setup(:default, 'sqlite::memory:') 36 37 class A 38 39 include DmConnector 40 include DataMapper::Resource 41 42 storage_names[:a_db] = 'a' 43 44 property :id, Serial 45 property :data, Text 46 47 connect_to_db 'sqlite3:a_db.sqlite3', :a_db 48 49 end 50 51 class B 52 53 include DmConnector 54 include DataMapper::Resource 55 56 storage_names[:b_db] = 'b' 57 58 property :id, Serial 59 property :data, Text 60 61 connect_to_db 'sqlite3:b_db.sqlite3', :b_db 62 63 end 64 65 DataMapper.finalize 66 67 puts("A objects count before create: #{A.count}") 68 puts("B objects count before create: #{B.count}") 69 70 a = A.create(:data => 'First A Object') 71 b = B.create(:data => 'First B Object') 72 73 puts("A objects count after one create: #{A.count}") 74 puts("B objects count after one create: #{B.count}") ------------------------------------------------------------------------ Running this program issues: ------------------------------------------------------------------------ /home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:147:in `execute_reader': no such table: as (DataObjects::SyntaxError) from /home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:147:in `block in read' from /home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:276:in `with_connection' from /home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:141:in `read' ... etc. from /home/nicb/tmp/test-wrong.rb:67:in `count' from /home/nicb/tmp/test-wrong.rb:67:in `<main>' ------------------------------------------------------------------------ which is related to the fact that the :default_repository_name method never gets overridden by the actual per-database context method (so the "default" method actually returns a wrongly-mangled table name). The next bit of code works: ------------------------------------------------------------------------ 1 begin 2 require 'ruby-debug' 3 Debugger.start 4 Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings) 5 rescue LoadError 6 # ruby-debug wasn't available so neither can the debugging be 7 end 8 9 require 'dm-core' 10 require 'dm-migrations' 11 12 module DmConnector 13 14 def self.included(base) 15 base.extend ClassMethods 16 end 17 18 module ClassMethods 19 20 @@connections = {} 21 22 def connect_to_db(dbname, context) 23 @@connections[context] = DataMapper.setup(context, dbname) unless @@connections.has_key?(context) 24 DataMapper.auto_upgrade!(context) 25 @@connections[context] 26 end 27 28 end 29 30 end 31 32 DataMapper.setup(:default, 'sqlite::memory:') 33 34 class A 35 36 include DmConnector 37 include DataMapper::Resource 38 39 def self.default_repository_name 40 :a_db 41 end 42 43 storage_names[:a_db] = 'a' 44 45 property :id, Serial 46 property :data, Text 47 48 connect_to_db 'sqlite3:a_db.sqlite3', :a_db 49 50 end 51 52 class B 53 54 include DmConnector 55 include DataMapper::Resource 56 57 def self.default_repository_name 58 :b_db 59 end 60 61 storage_names[:b_db] = 'b' 62 63 property :id, Serial 64 property :data, Text 65 66 connect_to_db 'sqlite3:b_db.sqlite3', :b_db 67 68 end 69 70 DataMapper.finalize 71 72 puts("A objects count before create: #{A.count}") 73 puts("B objects count before create: #{B.count}") 74 75 a = A.create(:data => 'First A Object') 76 b = B.create(:data => 'First B Object') 77 78 puts("A objects count after one create: #{A.count}") 79 puts("B objects count after one create: #{B.count}") ------------------------------------------------------------------------ but it involves way too many repetitions to be acceptable as serious code. Needless to say I've been looking wide and large if there is already a plugin or something that that would do the job for me, but to no avail. Also, using DataMapper::Model.append_inclusions does not solve the problem. What am I doing wrong? Can someone help please? Thank you for all the work Nicola -- You received this message because you are subscribed to the Google Groups "DataMapper" group. To view this discussion on the web visit https://groups.google.com/d/msg/datamapper/-/a4G1G_ra1A4J. To post to this group, send email to datamapper@googlegroups.com. To unsubscribe from this group, send email to datamapper+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/datamapper?hl=en.