问题
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
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
Finally, in the controller
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!
回答1:
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 }
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
This is Ruby where classes are objects too.
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
来源:https://stackoverflow.com/questions/10723955/problems-while-making-a-generic-model-in-ruby-on-rails-3