我正在尝试动态创建一个类,并将多个数据库连接之一分配给每个类。
我正在使用两个或三个随时间变化的数据库之间的任何地方,因此,我犹豫是否将每个连接字符串存储在单独的类中并从中继承而不是 ActiveRecord::Base。
下面抛出一个错误"运行时错误:不允许匿名类",但我不确定如何解决它,或者是否有更好的选择。
class ClassFactory
def self.create_class(new_class, table, db_connection)
c = Class.new(ActiveRecord::Base) do
db = db_connection
self.table_name = table
establish_connection(:adapter => db.database_type, :host => db.host, :database => db.database, :username => db.username, :password => db.password).connection
end
Module.const_set new_class, c
end
end
根据ActiveRecord::ConnectionHandling#establish_connection
的源代码,您无法从 name
不返回真实值的类建立连接。
现在,您将使用 const_set
将类分配给一个常量,这将给它一个名称。但是您需要在致电establish_connection
之前执行此操作:
class ClassFactory
def self.create_class(new_class, table, db_connection)
c = Class.new(ActiveRecord::Base) do
db = db_connection
self.table_name = table
end
Module.const_set new_class, c
c.establish_connection(:adapter => db.database_type, :host => db.host, :database => db.database, :username => db.username, :password => db.password).connection
end
end
另外,你真的想要Module.const_set(...)
吗?这将生成一个名为 Module::Foo
的类。可能你只是想要Object.const_set(...)
(这只会给Foo
(?甚至const_set(...)
,所以你得到ClassFactory::Foo
?
动态设置模型establish_connection
:
数据库.yml
development:
adapter: mysql
username: root
password:
database: example_development
oracle_development:
adapter: oracle
username: root
password:
database: example_oracle_development
在代码的任何地方,您都可以更改模型的数据库连接:
User.establish_connection "oracle_#{RAILS_ENV}".to_sym
您还可以动态创建模型类:
class ClassFactory
def self.create_class(new_class, table, connection_name)
Object.const_set(new_class, Class.new(ActiveRecord::Base) {})
new_class.constantize.table_name = table
new_class.constantize.establish_connection(connection_name)
end
end
ClassFactory.create_class('NewUser', 'users', :development)
之后NewUser
类将可供使用。
此版本适用于 Rails 5.0 和 3.2。