no Rails, como faço para executar direta código SQL em um banco de dados diferente?
-
09-06-2019 - |
Pergunta
Aqui é o caso.
Eu estou escrevendo uma aplicação Rails, que irá monitorar a qualidade dos dados através de alguns bancos de dados específicos.Para fazer isso, eu preciso ser capaz de executar, direta consultas SQL sobre estas bases de dados - que, naturalmente, não são o mesmo que o utilizado para conduzir a aplicação Rails modelos.Em suma, isso significa que eu não posso usar o truque de passar pelo ActiveRecord da base de dados de conexão.
As bases de dados que eu preciso para conectar-se não são conhecidos em tempo de design (i.e.:Eu não posso colocar os seus dados no banco de dados.yaml).Em vez disso, eu tenho um modelo de 'database_details", que o usuário irá utilizar para inserir os detalhes de bancos de dados sobre o qual a aplicação irá executar consultas em tempo de execução.
Por isso, a ligação para esses bancos de dados realmente é dinâmico e os detalhes são resolvidos em tempo de execução, apenas.
Como posso fazer isso?
Obrigado,
Rollo
Solução
Eu tive uma situação como essa, em que eu tinha que ligar para centenas de diferentes instâncias de um aplicativo externo, e eu fiz o código semelhante ao seguinte:
def get_custom_connection(identifier, host, port, dbname, dbuser, password)
eval("Custom_#{identifier} = Class::new(ActiveRecord::Base)")
eval("Custom_#{identifier}.establish_connection(:adapter=>'mysql', :host=>'#{host}', :port=>#{port}, :database=>'#{dbname}', " +
":username=>'#{dbuser}', :password=>'#{password}')")
return eval("Custom_#{identifier}.connection")
end
Este tem a vantagem de não alterar o ActiveRecord::Base de ligação que seus modelos herdar, então você pode executar o SQL contra esta conexão e descartar o objeto quando você é feito com ele.
Outras dicas
Programaticamente, você pode estabelecer uma conexão usando uma chamada como esta
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
Como você vê, que você pode substituir o somedatabase por um database_model.database_name valor.mesmo com o adatpter e todos os
ActiveRecord::Base.establish_connection documentação
Em seguida, você pode usar
ActiveRecord::Base.find_by_sql("select * ")
para executar a consulta sql.
ActiveRecord::Base.find_by_sql documentação
Mr Matt estava certo se incompleto
Mais informações (desatualizado, mas ainda é útil para a abordagem de design) pode ser encontrado aqui e não se esqueça de ligar para o banco de dados normal quando você está feito :)
Você pode ser capaz de fazer isso através auto.establish_connection