Вопрос по ruby, ruby-on-rails – Проблемы при создании универсальной модели в Ruby on Rails 3

4

Я пытаюсь создать "общую модель" поэтому он может подключаться к любой таблице любой базы данных. Во-первых, я создал этот класс, который подключается к другой указанной базе данных (не используя схему)

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 и указывает имя таблицы

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

Но это дает мне эту ошибку:

undefined method `stringify_keys' for "users":String

Что может быть не так? Есть ли лучший способ сделать это? Заранее спасибо!

Какова цель абстрактного класса Db? sailor
Вы были разработчиком Java? Kevin Bedell

Ваш Ответ

1   ответ
12

Почему не простосоздатьActiveRecord::Base subclass во время выполнения и избежать всех хлопот?

t = 'some_table'
c = Class.new(ActiveRecord::Base) { self.table_name = t }

затемc относится к классу AR дляsome_table и вы можете делать обычные вещи:

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, где классы тоже являются объектами.

Если вам нужно подключиться к другой базе данных, вы можете поставитьestablish_connection позвонить в блок вместе с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
@JonathanNesbitt Есть ли у вас какие-либо обходные пути? Может быть, что-то неприятное с использованием одного из методов eval или exec сработает. Или откажитесь от ActiveRecord в пользу чего-то более гибкого.
Это очень похоже на то, что я мог бы использовать, чтобы решитьthis problem - Был бы очень признателен, если бы вы могли взглянуть и дать мне какой-то вклад?
Анонимные классы ActiveRecord не поддерживаются в Rails 4:github.com/rails/rails/issues/8934
Спасибо большое, классно! pablomarti

Похожие вопросы