I have the following code that run on heroku inside a controller that intermittently fails. It’s a no-brainer that it should work to me, but I must be missing something.
@artist = Artist.find(params[:artist_id])
The parameters hash looks like this:
{"utf8"=>"������",
"authenticity_token"=>"XXXXXXXXXXXXXXX",
"password"=>"[FILTERED]",
"commit"=>"Download",
"action"=>"show",
"controller"=>"albums",
"artist_id"=>"62",
"id"=>"157"}
The error I get looks like this:
ActiveRecord::StatementInvalid: Mysql::Error: : SELECT `artists`.* FROM `artists` WHERE `artists`.`id` = ? LIMIT 1
notice the WHEREartists.id= ? part of the statement? It’s trying to find an ID of QUESTION MARK. Meaning Rails is not passing in the params[:artist_id] which is obviously in the params hash. I’m at complete loss.
I get the same error on different pages trying to select the record in a similar fashion.
My environment: Cedar Stack on Heroku (this only happens on Heroku), Ruby 1.9.3, Rails 3.2.8, files being hosted on Amazon S3 (though I doubt it matters), using the mysql gem (not mysql2, which doesn’t work at all), ClearDB MySQL database.
Here’s the full trace.
Any help would be tremendously appreciated.
try sql?
If it’s just this one statement, and it’s causing production problems, can you omit the query generator just for now? In other words, for very short term, just write the SQL yourself. This will buy you a bit of time.
ARel/MySQL explain?
Rails can help explain what MySQL is trying to do:
Perhaps you can discover some kind of difference between the queries that are succeeding vs. failing, such as how the
explainuses indexes or optimizations.mysql2 gem?
Can you try changing from the mysql gem to the mysql2 gem? What failure do you get when you switch to the mysql2 gem?
volatility?
Perhaps there’s something else changing the params hash on the fly, so you see it when you print it, but it’s changed by the time the query runs?
Try assigning the variable as soon as you receive the params:
not the params hash?
You wrote “Meaning Rails is not passing in the params[:artist_id] which is obviously in the params hash.” I don’t think that’s the problem– I expect that you’re seeing this because Rails is using the “?” as a placeholder for a prepared statement.
To find out, run the commands suggested by @Mori and compare them; they should be the same.
prepared statements?
Could be a prepared statement cache problem, when the query is actually executed.
Here’s the code that is failing– and there’s a big fat warning.
Try configuring your database to turn off prepared statements, to see if that makes a difference.
In your
./config/database.ymlfile:bugs with prepared statements?
There may be a problem with Rails ignoring this setting. If you want to know a lot more about it, see this discussion and bug fix by Jeremey Cole and Aaron: https://github.com/rails/rails/pull/7042
Heroku may ignore the setting. Here’s a way you can try overriding Heroku by patching the prepared_statements setup: https://github.com/rails/rails/issues/5297
remove the query cache?
Try removing the ActiveRecord QueryCache to see if that makes a difference:
try postgres?
If you can try Postgres, that could clear it up too. That may not be a long term solution for you, but it would isolate the problem to MySQL.