Ir para o conteúdo
ou

Software livre Brasil

 Voltar a Projeto Soft...
Tela cheia Sugerir um artigo

AJ O. Alves: Conexão com múltiplas DBs no Ruby On Rails

27 de Novembro de 2012, 0:00 , por Software Livre Brasil - 0sem comentários ainda | Ninguém está seguindo este artigo ainda.
Visualizado 125 vezes

Que o framework Ruby on Rails é uma mão na roda para várias das situações do cotidiano dos desenvolvedores WEB não é segredo. No entanto algumas vez é necessário fazer algumas tarefas que não são tão comuns, como por exemplo conectar nossa aplicação em vários bancos de dados.

Imagem de www.askqtp.com

Então, vamos lá! Mostrarei a vocês como fazer o ActiveRecord (Classe para abstrair o nível de Banco de Dados) conectar-se a múltiplos banco de dados relacionais (Em um postagem futuro mostrarei como trabalhar com NoSQL), semelhantes, ou diversos dentre SQLite, MySQL, PostgreSQL, OracleSQL, SQL Server

Aplicação de Exemplo: Quero cria uma aplicação para gerenciar projetos. No entanto quero que a tabela de usuário fique em uma base da dados externa a aplicação para que outras aplicações futuras também utilizarem essa base de usuários unificada.

Passo 1: Configurar seu database.yml

O primeiro passo, é configurar seu config/database.yml para realizar suas conexões, por exemplo, temos este arquivo:

# SQLite version 3.x#   gem install sqlite3##   Ensure the SQLite 3 gem is defined in your Gemfile#   gem 'sqlite3'development:  adapter: sqlite3  database: db/development.sqlite3  pool: 5  timeout: 5000

# Warning: The database defined as "test" will be erased and# re-generated from your development database when you run "rake".# Do not set this db to the same as development or production.test:  adapter: sqlite3  database: db/test.sqlite3  pool: 5  timeout: 5000

production:  adapter: sqlite3  database: db/production.sqlite3  pool: 5  timeout: 5000

Este é o padrão de criação com uma base no SQLite, por padrão configuradas com o nome dos ambientes de execução, vamos agora montar uma nova configuração, chamei ela de “database_externa_1” note que faremos conexão com um banco MySQL, o que é perfeitamente possível, já que o árduo trabalho de saber como lidar com cada tipo de base de dados é do ActiveRecord. Lembre também de referenciar as GENs dos adapters que estiver utilizando, neste exemplo “gem ‘sqlite3′; gem ‘mysql2′;

development:  adapter: sqlite3  database: db/development.sqlite3  pool: 5  timeout: 5000

test:  adapter: sqlite3  database: db/test.sqlite3  pool: 5  timeout: 5000

production:  adapter: sqlite3  database: db/production.sqlite3  pool: 5  timeout: 5000

database_externa_1:  adapter: mysql2  encoding: utf8  database: test_db  pool: 5  username: root  password: root  host: localhost

Passo 2: Criar uma Classe para manipular a conexão

O segundo passo é criar uma classe que servira para manipular a nova conexão, para isso, primeira vamos criar um arquivo chamado “my_databases.rb” dentro da pasta “config/initializers/“,  tudo que precisamos agora é criar uma classe que herde a classe ActiveRecord::Base, por exemplo:

class ProjectDB < ActiveRecord::Base    self.abstract_class = true    establish_connection Rails.env.to_symend

class TestDB < ActiveRecord::Base    self.abstract_class = true    establish_connection :database_externa_1end

Muita atenção neste ponto!!! Porque eu criei duas classe?!
Basicamente por organização e simplicidade, para que cada modelo fique explicitamente vinculado a qual conexão ele pertence!

A primeira classe “ProjectdDB” faz referência as conexões padrões (:development, :test, :production) em SQLite. Note no valor que é passado ao método “establish_connection” que é Rails.env.to_sym.

A segunda classe “TestDB” faz referência a nossa base de dados externa em MySQL.
Obs:.  “self.abstract_class = true” significa dizer que a classe é abstrata, ou seja, não pode ser instanciada só herdada.

Neste ponto já possuímos toda a nossa aplicação configurada para trabalhar com base de dados distintas. Agora mostrarei através de exemplos como devemos trabalhar.

Exemplo 1: Criar a tabela de usuários.

rails generate scaffold user name:string email:string      invoke  active_record      create    db/migrate/20121127205353_create_users.rb      create    app/models/user.rb      invoke    test_unit      create      test/unit/user_test.rb      create      test/fixtures/users.yml      invoke  resource_route       route    resources :users      invoke  scaffold_controller      create    app/controllers/users_controller.rb      invoke    erb      create      app/views/users      create      app/views/users/index.html.erb      create      app/views/users/edit.html.erb      create      app/views/users/show.html.erb      create      app/views/users/new.html.erb      create      app/views/users/_form.html.erb      invoke    test_unit      create      test/functional/users_controller_test.rb      invoke    helper      create      app/helpers/users_helper.rb      invoke      test_unit      create        test/unit/helpers/users_helper_test.rb      invoke  assets      invoke    coffee      create      app/assets/javascripts/users.js.coffee      invoke    scss      create      app/assets/stylesheets/users.css.scss      invoke  scss      create    app/assets/stylesheets/scaffolds.css.scss

Como a tabela de usuários deve ficar na base externa devemos tomar alguns procedimentos:

1º – Alterar o arquivo app/models/user.rb

class User < ActiveRecord::Base    attr_accessible :email, :nameend

para:

class User < TestDB    attr_accessible :email, :nameend

substituir o ActiveRecord::Base por sua subclasse TestDB, assim, a aplicação se onde encontrar a tabela users que será criada.

2º – Radar a migração de forma apropriada

rake db:migrate RAILS_ENV=database_externa_1   ==  CreateUsers: migrating   ====================================================   -- create_table(:users)      -> 0.0711s   ==  CreateUsers: migrated (0.0712s)   ===========================================

passando a conexão  “database_externa_1” como parâmetro, assim, a tabela será criada no banco externo.

Exemplo 2: Criar a tabela de projetos.

rails generate scaffold project user_id:integer name:string description:text      invoke  active_record      create    db/migrate/20121127212538_create_projects.rb      create    app/models/project.rb      invoke    test_unit      create      test/unit/project_test.rb      create      test/fixtures/projects.yml      invoke  resource_route       route    resources :projects      invoke  scaffold_controller      create    app/controllers/projects_controller.rb      invoke    erb      create      app/views/projects      create      app/views/projects/index.html.erb      create      app/views/projects/edit.html.erb      create      app/views/projects/show.html.erb      create      app/views/projects/new.html.erb      create      app/views/projects/_form.html.erb      invoke    test_unit      create      test/functional/projects_controller_test.rb      invoke    helper      create      app/helpers/projects_helper.rb      invoke      test_unit      create        test/unit/helpers/projects_helper_test.rb      invoke  assets      invoke    coffee      create      app/assets/javascripts/projects.js.coffee      invoke    scss      create      app/assets/stylesheets/projects.css.scss      invoke  scss      identical    app/assets/stylesheets/scaffolds.css.scss

Como a tabela de projetos deve ficar na base local:

1º – Alterar o arquivo app/models/project.rb

class Project < ActiveRecord::Base    attr_accessible :description, :name, :user_idend

para:

class Project < ProjectDB    attr_accessible :description, :name, :user_id

    belongs_to :userend

substituir o ActiveRecord::Base por sua subclasse ProjectDB. Note que toda as relações entre os modelos podem ser construídas normalmente, para a aplicação não faz mais diferença a sua localidade ou tipo. Então configure o modelo “user” também:

class User < TestDB    attr_accessible :email, :name

    has_many :projectsend

2º – Radar a migração de forma apropriada

rake db:migrate   ==  CreateUsers: migrating   ====================================================   -- create_table(:users)      -> 0.0014s   ==  CreateUsers: migrated (0.0015s)   ===========================================   ==  CreateProjects: migrating   =================================================   -- create_table(:projects)      -> 0.0014s   ==  CreateProjects: migrated (0.0015s)   ========================================

Veja que não a necessidade de passar a conexão com o parâmetro, pois será utilizada a padrão do ambiente.
Agora, todos os modelos do seu projeto devem herdar de ProjecDB e não mais de ActiveRecord::Base.
Pronto, isso é tudo o que você deve saber para trabalhar com múltiplas base de dados relacionais em seu projeto Ruby on Rails.

Para testar, vá ao terminal:

rails cLoading development environment (Rails 3.2.8)1.9.3p194 :001 > User.create(:name => "AJ Alves", :email => "aj.alves@zerokol.com")   (0.1ms)  BEGIN  SQL (0.3ms)  INSERT INTO `users` (`created_at`, `email`, `name`, `updated_at`) VALUES ('2012-11-27 21:37:28', 'aj.alves@zerokol.com', 'AJ Alves', '2012-11-27 21:37:28')   (36.6ms)  COMMIT => #<user 21:37:28="21:37:28" 2="2" aj.alves="aj.alves" alves="alves" created_at:="created_at:" email:="email:" id:="id:" name:="name:" updated_at:="updated_at:" zerokol.com="zerokol.com"> 1.9.3p194 :002 > Project.create(:user_id => 1, :name => "Teste", :description => "Um projeto de teste")   (0.0ms)  begin transaction  SQL (0.4ms)  INSERT INTO "projects" ("created_at", "description", "name", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?)  [["created_at", Tue, 27 Nov 2012 21:38:16 UTC +00:00], ["description", "Um projeto de teste"], ["name", "Teste"], ["updated_at", Tue, 27 Nov 2012 21:38:16 UTC +00:00], ["user_id", 1]]   (117.6ms)  commit transaction => #<project 1="1" 21:38:16="21:38:16" 2="2" created_at:="created_at:" de="de" description:="description:" este="este" id:="id:" m="m" name:="name:" projeto="projeto" teste="teste" updated_at:="updated_at:" user_id:="user_id:"> 1.9.3p194 :003 > u = User.first  User Load (0.4ms)  SELECT `users`.* FROM `users` LIMIT 1 => #<user 1="1" 21:33:42="21:33:42" aj.zerokol="aj.zerokol" alves="alves" created_at:="created_at:" email:="email:" gmail.com="gmail.com" id:="id:" name:="name:" updated_at:="updated_at:"> 1.9.3p194 :004 > u.projects  Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."user_id" = 1 => [#<project 1="1" 21:33:58="21:33:58" created_at:="created_at:" d="d" description:="description:" dsfsdf="dsfsdf" este="este" id:="id:" name:="name:" sdf="sdf" sdfs="sdfs" updated_at:="updated_at:" user_id:="user_id:">, #<project 1="1" 21:38:16="21:38:16" 2="2" created_at:="created_at:" de="de" description:="description:" este="este" id:="id:" m="m" name:="name:" projeto="projeto" teste="teste" updated_at:="updated_at:" user_id:="user_id:">] 1.9.3p194 :005 > p = Project.first  Project Load (0.2ms)  SELECT "projects".* FROM "projects" LIMIT 1 => #<project 1="1" 21:33:58="21:33:58" created_at:="created_at:" d="d" description:="description:" dsfsdf="dsfsdf" este="este" id:="id:" name:="name:" sdf="sdf" sdfs="sdfs" updated_at:="updated_at:" user_id:="user_id:"> 1.9.3p194 :006 > p.user  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 => #<user 1="1" 21:33:42="21:33:42" aj.zerokol="aj.zerokol" alves="alves" created_at:="created_at:" email:="email:" gmail.com="gmail.com" id:="id:" name:="name:" updated_at:="updated_at:"> 1.9.3p194 :007 >

Fonte: http://www.zerokol.com/2012/11/conexao-com-multiplas-dbs-no-ruby-on.html

0sem comentários ainda

Enviar um comentário

Os campos são obrigatórios.

Se você é um usuário registrado, pode se identificar e ser reconhecido automaticamente.