Como posso converter esse código em sql bruto e usar em trilhos? Como quando implanto esse código no heroku, há um erro de tempo limite da solicitação. Acho que isso será mais rápido se eu usar o sql bruto.
@payments = PaymentDetail.joins(:project).order('payment_details.created_at desc')
@payment_errors = PaymentError.joins(:project).order('payment_errors.created_at desc')
@all_payments = (@payments + @payment_errors)
sql
ruby-on-rails
Johnny Cash
fonte
fonte
Respostas:
Você consegue fazer isso:
records_array
seria o resultado da sua consulta sql em uma matriz pela qual você pode iterar.fonte
records_array
será de tipos diferentes para diferentes adaptadores de banco de dados. Se você estiver usando PG, será uma instânciaPG::Result
, nãoArray
.values
essePG::Result
objeto para obter a matriz de resultadosActiveRecord::Base.connection.exec_query
mais porque retorna umActiveRecords::Result
objeto que possui métodos úteis, como.columns
e.rows
para acessar cabeçalhos e valores. A matriz de hashes de.execute
pode ser problemática de lidar e me deu resultados redundantes quando executei uma cláusula SUM GROUP BY.Eu sei que isso é antigo ... Mas eu estava tendo o mesmo problema hoje e encontrei uma solução:
Se você deseja instanciar os resultados:
Se você quer apenas um hash de valores:
Objeto de resultado:
select_all
retorna umresult
objeto. Você pode fazer coisas mágicas com isso.Fontes:
fonte
#find_by_sql
é exatamente o que eu queria, muito obrigado.Você pode executar uma consulta bruta usando
ActiveRecord
. E eu vou sugerir ir com bloco SQLfonte
SELECT * FROM users WHERE users.id = #{ user.id }
Você pode fazer o SQL direto ter uma única consulta para ambas as tabelas. Fornecerei um exemplo de consulta higienizada para evitar que as pessoas insiram variáveis diretamente na própria string (perigo de injeção de SQL), mesmo que este exemplo não tenha especificado a necessidade:
Edit : como Huy disse, é uma maneira simples
ActiveRecord::Base.connection.execute("...")
. Outra maneira éActiveRecord::Base.connection.exec_query('...').rows
. E você pode usar instruções preparadas nativas, por exemplo, se estiver usando o postgres, a instrução preparada poderá ser feita com raw_connection, prepare e exec_prepared, conforme descrito em https://stackoverflow.com/a/13806512/178651Você também pode colocar fragmentos de SQL brutos nas consultas relacionais do ActiveRecord: http://guides.rubyonrails.org/active_record_querying.html e em associações, escopos etc. Você provavelmente pode construir o mesmo SQL com as consultas relacionais do ActiveRecord e pode fazer coisas interessantes ARel como Ernie menciona em http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ . E, claro, existem outras ORMs, gemas, etc.
Se isso for usado muito e a adição de índices não causará outros problemas de desempenho / recursos, considere adicionar um índice no banco de dados para payment_details.created_at e para payment_errors.created_at.
Se muitos registros e nem todos os registros precisarem aparecer ao mesmo tempo, considere usar a paginação:
Se você precisar paginar, considere criar uma visualização no banco de dados chamada payment_records que combine as tabelas payment_details e payment_errors e, em seguida, tenha um modelo para a visualização (que será somente leitura). Alguns bancos de dados oferecem suporte a visualizações materializadas, o que pode ser uma boa idéia para desempenho.
Considere também as especificações de hardware ou VM no servidor Rails e no servidor DB, configuração, espaço em disco, velocidade / latência da rede / etc., Proximidade etc. E considere colocar o DB em um servidor / VM diferente do aplicativo Rails, se você não tiver, etc. .
fonte
Eu quero trabalhar com
exec_query
aActiveRecord
classe, porque ela retorna o mapeamento da consulta transformada em objeto, para que seja muito prático e produtivo interagir com os objetos quando o assunto for Raw SQL.Exemplo:
e retorne esta consulta completa:
Para obter apenas lista de valores
Para obter apenas colunas de campos
fonte
Você também pode misturar SQL bruto com condições do ActiveRecord, por exemplo, se desejar chamar uma função em uma condição:
fonte