在Ruby on Rails 3中制作通用模型时出现问题
我正在尝试创建一个通用模型,以便它可以连接到任何数据库的任何表。首先,我制作了此类,它连接到指定的另一个数据库(不使用架构)
I'm trying to make a "generic model" so it can connect to any table of any database. First, I made this class which connects to another database specified (not using the schema)
Db
class Db < ActiveRecord::Base
self.abstract_class = true
attr_accessor :error
def initialize(item = nil)
@error = ""
connect
super
end
def connect
could_connect = true
@error = ""
begin
ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "localhost",
:username => "root",
:password => "",
:database => "another_database",
:port => 3306,
:encoding => "utf8"
)
rescue ActiveRecord::ConnectionNotEstablished
@error = "Could not connect to database. The connection was not established"
could_connect = false
rescue Mysql2::Error
@error = "Could not connect to database using MySQL2"
could_connect = false
rescue => e
@error = "Could not connect to database. #{e.message}."
could_connect = false
end
return could_connect
end
end
然后,我做了一个从Db继承并指定表名的类
Then, I made this class which inherits from Db and specifies the table name
Gmodel
class Gmodel < Db
def initialize(new_table_name)
ActiveRecord::Base.set_table_name(new_table_name)
super
end
end
最后,在控制器中
MainController
class MainController < ApplicationController
def index
@users = Gmodel.new("users")
end
end
但是,它给了我这个错误:
But, it gaves me this error:
undefined method `stringify_keys' for "users":String
有什么问题吗?有更好的方法吗?
What could be wrong? Is there some better way to do this? Thanks in advance!
为什么不简单地在运行时创建 ActiveRecord :: Base
子类,并避免所有麻烦吗?
Why not simply create an ActiveRecord::Base
subclass at runtime and avoid all the hassle?
t = 'some_table'
c = Class.new(ActiveRecord::Base) { self.table_name = t }
然后 c
指的是 some_table
,您可以执行常规操作:
then c
refers to an AR class for some_table
and you can do the usual things:
o = c.find(1)
# 'o' is now a wrapper for the row of some_table where 'id = 1'
cols = c.columns.map(&:name)
# 'cols' is now an array of some_table's column names
这也是在Ruby中类也是对象的地方。
This is Ruby where classes are objects too.
如果需要连接到另一个数据库,则可以将 Establishment_connection
调用与 self.table_name
:
If you need to connect to another database then you can to put the establish_connection
call in the block along with the self.table_name
:
t = 'some_table'
d = 'some_other_database'
c = Class.new(ActiveRecord::Base) do
establish_connection(:adapter => 'mysql2', :database => d, ...)
self.table_name = t
end