ActiveRecord::StatementInvalid: Mysql2::Error when using association name in .where method instead of foreign key - mysql

We just updated our Rails App from 3.0.13 to 3.2.6 and have encountered a minor problem when using the .where method of the Active Record Query Interface with mysql2.
What used to work before:
client = Client.first
User.where(:client => client)
now leads to:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column
'users.client' in 'where clause': SELECT users.* FROM users WHERE
users.client = 1
But when explicitly using the column name of the foreign key, it seems to work just fine:
client = Client.first
User.where(:client_id => client.id)
#=> Relation of users with the given client_id
The associations have not changed (users belong to client, client has many users). This now seems to be the problem with every association of this kind.
Do we now really have to change all these where queries so that they use the foreign_key or is there any other way?
rails version:
gem "rails", "~> 3.2.6"
mysql2 version:
gem "mysql2", "~> 0.3.11"

We just found out that this functionality was provided by a gem called meta_where, which is deprecated in Rails 3.1+.
There is an alternative, squeel, which unfortunately doesn't provide the exact same syntax. (Or we just haven't found out yet...)
Investigating now...
Thanks #zsquare for pointing out.

Related

ActiveRecord not behaving as I expect it

Ruby 2.0
Windows 8.1
Rails 4.1
MySQL2 gem
To avoid an error, I am using the following code to check for an existing payment, prior to creating a new payment record:
payment = {"organization_id" => organization_id,
"date" => row[1],
"amount" => row[2],
"description" => row[3]}
slug = "#{organization_id.to_s}_#{row[1].to_s}_#{row[2].to_s}_#{row[3]})
organization_payment = OrganizationPayment.where(:slug => slug)[0]
if !organization_payment
new_organization_payment = OrganizationPayment.create(payment)
end
Every once in a while, I am getting the following error:
Mysql2::Error at /process_uploaded_payments_data
Duplicate entry 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' for key 'index_organization_payments_on_slug'
I also have the following in my model:
validates_uniqueness_of :slug
Is there any reason why the entry causing the duplicate error would not have been caught by the code above? Any ideas?
Solution
I am still not certain what caused the problem, but I learned the hard way that validating uniqueness does not really work, if you also have a before_save call in your model that creates the slug in question. The workaround is an exception handler:
begin
new_organization_payment = OrganizationPayment.create(payment)
rescue ActiveRecord::RecordNotUnique
next
end
I don't know if this is your problem but a possible cause of this could be race condition -- when your code is running in a process it can be interrupted right after the if condition before it creates the new record.
Putting a unique constraint on the column in the database is a fine way of dealing with this problem, though. You can catch the exception and deal with it that way. You also don't have to manually check for the duplicity, you can use active record validations; fetching the entire record just to check if it exists is not the best practice anyway. More info:
http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of

Mysql2::Error: Unknown column '6' in 'where clause': SELECT

I am upgrading my Rails app from Rails 2.3 to 3.2.
and I am getting this weird error
Mysql2::Error: Unknown column '6' in 'where clause':
above error is due to `(backtick) which is applied to data in the where clause along with the column names see the following query.
Mysql2::Error: Unknown column '6' in 'where clause': SELECT `users`.`username`,`users`.`password` FROM `users` WHERE `id` IN (`6`)
see the 6 even though it is data activerecord is applying backtick to it.because of that mysql is raising exception.
NOTE:This is usually seen while calling related object(one to one,many to many)
eg:
u = User.where(:active =>true).each{|u|
//some code
u.user_role #error will raise in this line
}
if I reinitiate the object it will work fine.
u = User.where(:active =>true).each{|u|
//some code
u.user_role #error will raise in this line
u1 = User.find(u.id)
u1.user_role #works fine.
}
This is happening throughout the application and with other models as well,above code snippet is just one instance.
Environment details:
OS: Ubuntu 13.10,Ruby 1.9.3-p545,Rails 3.2.17 mysql 5.5
Anyone knows what going on here ? is it because of gem incompatibility ?
Please let me know if you need some more details.
This issue is due to gem incompatibility.I was using 'slim_scrooge' gem to optimize queries in Rails 2.X doesn't gem well with Rails 3 or higher.
I am not sure why this may be coming, but I think you can avoid this and an extra query to sql while accessing user_role by using include in your query. This will eager load user_role in the first query itself and will not make extra query in each loop.
Code will be something like following:
u = User.where(:active =>true).includes(:user_roles).each{|u|
//some code
u.user_role #error will raise in this line
}
More details on include is here: http://apidock.com/rails/ActiveRecord/QueryMethods/includes

Connecting to an external MySQL server for legacy data on heroku using ActiveRecord

So I am building a new app that needs to do some importing of legacy data from an old app. The old apps database is mysql, which you obviously can't use on heroku, but I want to use postgres. Basically I am doing an ETL via activerecord.
Here's what I have so far:
# config/initializers/legacy_database.rb
LEGACY_DATABASE_URL = "mysql://myusername:#{ENV['LEGACY_DATABASE_PASSWORD']}#host/foo1008801154002"
# app/models/legacy.rb
class Legacy < ActiveRecord::Base
establish_connection LEGACY_DATABASE_URL
end
# app/models/legacy/user.rb
class Legacy::User < Legacy
self.table_name = 'users'
end
If I am in the console and I run Legacy::User.count I get back the correct count. However if I try to do something like Legacy::User.first I get the following error:
Legacy::User Load (54.0ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
Mysql::Error: Table 'foo1008801154002.legacies' doesn't exist: SHOW FULL FIELDS FROM `legacies`
ActiveRecord::StatementInvalid: Mysql::Error: Table 'foo1008801154002.legacies' doesn't exist: SHOW FULL FIELDS FROM `legacies`
I'm not sure why rails is adding on the .legacies to the table name, nor am I sure how to fix this. I figure it might be some setting in Legacy.connection
Any advice?
Well it was relatively simple. I had to add the line self.abstract_class = true to my Legacy Base class.
Just a note: if you have mysql2 gem in your bundle then need to put:
# config/initializers/legacy_database.rb
LEGACY_DATABASE_URL = "mysql2://myusername:#{ENV['LEGACY_DATABASE_PASSWORD']}#host/foo1008801154002"
(or load mysql gem in Gemfile)

Bind parameters in Rails mySQL empty

Using Rails 3.1.1, I'm getting occasional errors in production where it seems like the bind parameters on a mysql query are not there for some reason. The error looks like this:
A ActiveRecord::StatementInvalid occurred in events#show:
Mysql::Error: : SELECT `events`.* FROM `events` WHERE `events`.`id` = ? LIMIT 1
activerecord (3.1.1) lib/active_record/connection_adapters/mysql_adapter.rb:890:in `execute
It's not consistent on any insert or select, so I'm having trouble tracking it down. Does anybody have any suggestions?
Edit: updated with simpler example.
#events_controller.rb
def show
#event = Event.find(params[:id])
...
end
#called with parameters: {"action"=>"show", "controller"=>"events", "id"=>"26"}
The probable reason
Check your database driver installation here.
This seems to have gone away after upgrading to the latest rails - uncertain as to what it was.

Rails unit tests fail because of unique constraint on schema_migrations

I'm trying to run rake test:units and I keep getting this:
Mysql::Error: Duplicate entry '2147483647' for key 1: INSERT INTO `ts_schema_migrations` (version) VALUES ('20081008010000')
The "ts_" is there because I have ActiveRecord::Base.table_name_prefix set. I'm confused because there is no value '20081008010000' already in the table, and there is no migration with the value '2147483647' (though the value does appear in the table).
In Rails' schema_statments.rb, there is the following:
def initialize_schema_migrations_table
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
unless tables.detect { |t| t == sm_table }
create_table(sm_table, :id => false) do |schema_migrations_table|
schema_migrations_table.column :version, :string, :null => false
end
...
In my development database, ts_schema_migrations.version is a VARCHAR. In test, though it's an INTEGER. I've dropped the tables and re-run the migrations (and/or a rake db:schema:load RAILS_ENV=test) several times. No changes.
Is something wrong with my MySQL adapter?
It looks as though your test schema is Rails 1.x somehow, whereas development is Rails 2. Perhaps you could set RAILS_ENV to test and run rake db:reset
It looks like you skipped some steps when upgrading from Rails 1.x to 2.0.
Go through and read the upgrade notes:
http://www.slashdotdash.net/2007/12/03/rails-2-upgrade-notes/
And the release notes:
http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done
They will tell you all the steps you need to follow. Particularly regenerating all the scripts and migrating your database to the new system of database migrations by timestamp instead of incrementing migration id.