experimentar sql?
Se for apenas esta declaração e estiver causando problemas de produção, você pode omitir o gerador de consulta por enquanto? Em outras palavras, para um prazo muito curto, basta escrever o SQL você mesmo. Isso vai lhe dar um pouco de tempo.
# All on one line:
Artist.find_by_sql
"SELECT `artists`.* FROM `artists`
WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"
ARel/MySQL explica?
Rails pode ajudar a explicar o que o MySQL está tentando fazer:
Artist.find(params[:artist_id]).explain
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
Talvez você possa descobrir algum tipo de diferença entre as consultas que estão sendo bem-sucedidas e as que falham, por exemplo, como o
explain
usa índices ou otimizações. gem do mysql2?
Você pode tentar mudar da gem mysql para a gem mysql2? Que falha você obtém quando muda para a gem mysql2?
volatilidade?
Talvez haja algo mais alterando o hash de params em tempo real, então você o vê quando o imprime, mas é alterado no momento em que a consulta é executada?
Tente atribuir a variável assim que receber os parâmetros:
artist_id = params[:artist_id]
... whatever code here...
@artist = Artist.find(artist_id)
não é o hash de parâmetros?
Você escreveu "O que significa que Rails não está passando no params[:artist_id] que obviamente está no hash de params." Eu não acho que esse seja o problema-- espero que você esteja vendo isso porque o Rails está usando o "?" como um espaço reservado para uma declaração preparada.
Para descobrir, execute os comandos sugeridos por @Mori e compare-os; Eles deveriam ser os mesmos.
Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql
declarações preparadas?
Pode ser um problema de cache de instrução preparada, quando a consulta é realmente executada.
Aqui está o código que está falhando - e há um grande aviso.
begin
stmt.execute(*binds.map { |col, val| type_cast(val, col) })
rescue Mysql::Error => e
# Older versions of MySQL leave the prepared statement in a bad
# place when an error occurs. To support older mysql versions, we
# need to close the statement and delete the statement from the
# cache.
stmt.close
@statements.delete sql
raise e
end
Tente configurar seu banco de dados para desativar as instruções preparadas, para ver se isso faz diferença.
Em seu
./config/database.yml
Arquivo:production:
adapter: mysql
prepared_statements: false
...
bugs com declarações preparadas?
Pode haver um problema com o Rails ignorando esta configuração. Se você quiser saber muito mais sobre isso, veja esta discussão e correção de bug por Jeremey Cole e Aaron:https://github.com/rails/rails/pull/7042
Heroku pode ignorar a configuração. Aqui está uma maneira de tentar substituir o Heroku corrigindo a configuração de prepare_statements:https://github.com /rails/rails/issues/5297
remover o cache de consulta?
Tente remover o ActiveRecord QueryCache para ver se isso faz alguma diferença:
config.middleware.delete ActiveRecord::QueryCache
http://edgeguides.rubyonrails.org/configuring.html#configuring-middle
experimentar postgres?
Se você puder tentar o Postgres, isso também pode esclarecer. Isso pode não ser uma solução de longo prazo para você, mas isolaria o problema do MySQL.