1

Have a database with multiple tables. All tables have the same structure. I am writing a small web application to work with this database on Ruby / Sinatra. I want to simplify the work with tables using ORM - Active Record or DataMapper (preferred). The manuals for the use of a single model for multiple tables offer something like:

class Table
   include DataMapper::Resource
   property id, Serial
   property item, String
end

class TableA < Table
   self.table_name = 'table_a'
end

class TableB < Table
   self.table_name = 'table_b'
end

How this can be done for several dozen tables without copypaste?

If possible, the decision should be the possibility to add / remove the table without changing the code / settings and restart the application.

Something like:

# Model declaration

DataMapper.finalize

itemA = Table.new (use_table: 'table_a')
itemB = Table.new (use_table: 'table_b')
Reisenfag
  • 11
  • 2

1 Answers1

0

One of the ways to achive this is using eval.

class Table
   include DataMapper::Resource
   property id, Serial
   property item, String
end

table_names = {'TableA' => 'table_a', 'TableB' => 'table_b'}

table_names.each do |klass_name, table_name|
eval <<DYNAMIC
  class #{klass_name} < Table
    self.table_name = '#{table_name}'
  end
DYNAMIC
end
nishu
  • 1,493
  • 11
  • 26
  • As a solution is possible, but not quite what is needed. Supplemented the question. – Reisenfag Jul 20 '14 at 13:58
  • It looks like you want to use a factory pattern. You can add a method in `Table` that will accept the `table_name` and return a subclass of `Table`. You can implement this method by adding a cache of all subclasses in `Table` indexed by their names. If you do not find the current name in the lookup you generate a new subclass and add it to the index. – nishu Jul 21 '14 at 08:03
  • I find solution in Active Record. This is code just work: `class Test < ActiveRecord::Base` `end` `Test.table_name = "tests_a"` `itema = Test.new` `itema.item = "aaa"` `itema.save` `Test.table_name = "tests_b"` `itemb = Test.new` `itemb.item = "bbb"` `itemb.save` – Reisenfag Jul 21 '14 at 13:10