2013-03-14 9 views
95

Ho bisogno di scrivere uno script ruby ​​autonomo che dovrebbe occuparsi del database. Ho usato il codice indicato di seguito in Rails 3Rails 3 esegue query sql personalizzate senza un modello

@connection = ActiveRecord::Base.establish_connection(
:adapter => "mysql2", 
:host => "localhost", 
:database => "siteconfig_development", 
:username => "root", 
:password => "root123" 
) 

results = @connection.execute("select * from users") 
results.each do |row| 
puts row[0] 
end 

ma ottenere errore: -

`<main>': undefined method `execute' for #<ActiveRecord::ConnectionAdapters::ConnectionPool:0x00000002867548> (NoMethodError) 

che cosa manco qui?

SOLUZIONE

Dopo aver ottenuto la soluzione da denis-bu ho usato come segue e che ha funzionato troppo.

@connection = ActiveRecord::Base.establish_connection(
      :adapter => "mysql2", 
      :host => "localhost", 
      :database => "siteconfig_development", 
      :username => "root", 
      :password => "root123" 
) 

sql = "SELECT * from users" 
@result = @connection.connection.execute(sql); 
@result.each(:as => :hash) do |row| 
    puts row["email"] 
end 

risposta

159

Forse provare questo :

ActiveRecord::Base.establish_connection(...) 
ActiveRecord::Base.connection.execute(...) 
+14

FWIW, l'utilizzo di parametri vu non è un rubino idiomatico. Quindi esegui 'connection.execute' piuttosto che' connection(). Execute' – radixhound

+0

Funziona anche su Rails 4. –

+1

Funziona davvero su Rails 4.0.5 –

4

ne dite di questo:

@client = TinyTds::Client.new(
     :adapter => 'mysql2', 
     :host => 'host', 
     :database => 'siteconfig_development', 
     :username => 'username', 
     :password => 'password' 

sql = "SELECT * FROM users" 

result = @client.execute(sql) 

results.each do |row| 
puts row[0] 
end 

È necessario avere installato TinyTds gioiello, dal momento che non è stato specificato che nella sua domanda non ho usato attivo Record

+0

ho ottenuto un errore costante non inizializzato TinyTds – neeraj

+1

Sure, TinyTds è l'altra gemma intera. Non è ActiveRecord. Per usarlo dovresti installarlo separatamente. –

+0

sì, avrei dovuto dire che – ant

97
connection = ActiveRecord::Base.connection 
connection.execute("SQL query") 
+8

In questo caso, connection = ActiveRecord :: Base.connection; connection.execute ("query SQL") funzionerebbe. Meno digitando! – Watusimoto

+16

Oppure solo 'ActiveRecord :: Base.connection.execute (" Query SQL ")' –

+3

Questa connessione potrebbe dover essere restituita al pool di connessioni in seguito per evitare problemi di threading: 'ActiveRecord :: Base.connection_pool.checkin (connessione)' http://apidock.com/rails/ActiveRecord/ConnectionAdapters/ConnectionPool – lee

24

Si potrebbe anche usare find_by_sql

# A simple SQL query spanning multiple tables 
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id" 
> [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...] 
+0

il mio script è esterno all'applicazione rails quindi non credo che find_by_sql possa funzionare. – neeraj

+4

hai ragione, ho letto la tua domanda troppo velocemente.Questa risposta potrebbe aiutare gli altri che visitano questa pagina in base al titolo della domanda. – montrealmike

+0

come ottenere non un array ma una relazione? –

26

Mi consiglia di utilizzare ActiveRecord::Base.connection.exec_query invece di ActiveRecord::Base.connection.execute che restituisce una ActiveRecord::Result (disponibile in rotaie 3.1+), che è un po 'più facile lavorare con.

Poi si può accedere in vari il risultato in vari modi, come .rows, .each, o .to_hash

Dal docs:

result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts') 
result # => #<ActiveRecord::Result:0xdeadbeef> 


# Get the column names of the result: 
result.columns 
# => ["id", "title", "body"] 

# Get the record values of the result: 
result.rows 
# => [[1, "title_1", "body_1"], 
     [2, "title_2", "body_2"], 
     ... 
    ] 

# Get an array of hashes representing the result (column => value): 
result.to_hash 
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"}, 
     {"id" => 2, "title" => "title_2", "body" => "body_2"}, 
     ... 
    ] 

# ActiveRecord::Result also includes Enumerable. 
result.each do |row| 
    puts row['title'] + " " + row['body'] 
end 

nota: copiato la mia risposta da here

+1

Come indicato, exec_query restituisce i risultati effettivi: cosa voglio, mentre eseguire appena restituisce informazioni sullo stato. –

Problemi correlati