Problems while making a generic model in Ruby on Rails 3

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!