When passing hash conditions on a joined association to find(), I
expected ActiveRecord to interpret the hash key as the association
name and use the corresponding table name in the query. However, it
seems to be interpreting the hash key as the table name.
Given these:
class Foo < ActiveRecord::Base
has_many :bars
end
class Bar < ActiveRecord::Base
set_table_name 'some_bars'
end
I expected :bars to be treated as the association name – not the
table name – to which :name => “baz” is applied.
f = Foo.create
b = f.bars.create :name => "baz"
assert_nothing_raised do
res = Foo.find :all, :conditions => { :bars => { :name => "baz" }
},
:joins => :bars
assert_equal c.id, res.first.id
end
Running this test results in the following failure. I expected the
query condition to have “some_bars”.“name”, not “bars”.“name”.
- Failure:
test_include_with_set_table_name_uses_table_not_class_name(IncludeWithSetTableNameTest)
[./test/cases/associations/nested_conditions_with_set_table_name_test.rb:38:in
test_include_with_set_table_name_uses_table_not_class_name' ./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:62:in
send’
./test/cases/…/…/…/activesupport/lib/active_support/testing/setup_and_teardown.rb:62:in
run']: Exception raised: Class: <ActiveRecord::StatementInvalid> Message: <"SQLite3::SQLException: no such column: bars.name: SELECT \"foos\".* FROM \"foos\" INNER JOIN \"some_bars\" ON some_bars.foo_id = foos.id WHERE (\"bars\".\"name\" = 'baz') "> ---Backtrace--- ./test/cases/../../lib/active_record/connection_adapters/abstract_adapter.rb:219:in
log’
./test/cases/…/…/lib/active_record/connection_adapters/sqlite_adapter.rb:172:in
execute_without_query_record' ./test/cases/../../lib/active_record/connection_adapters/sqlite_adapter.rb:417:in
catch_schema_changes’
./test/cases/…/…/lib/active_record/connection_adapters/sqlite_adapter.rb:172:in
execute_without_query_record' ./test/cases/helper.rb:36:in
execute’
./test/cases/…/…/lib/active_record/connection_adapters/sqlite_adapter.rb:320:in
select' ./test/cases/../../lib/active_record/connection_adapters/abstract/database_statements.rb:7:in
select_all_without_query_cache’
./test/cases/…/…/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in
select_all' ./test/cases/../../lib/active_record/base.rb:661:in
find_by_sql’
./test/cases/…/…/lib/active_record/base.rb:1548:infind_every' ./test/cases/../../lib/active_record/base.rb:615:in
find’
./test/cases/associations/nested_conditions_with_set_table_name_test.rb:39:in
test_include_with_set_table_name_uses_table_not_class_name' ./test/cases/associations/nested_conditions_with_set_table_name_test.rb:38:in
test_include_with_set_table_name_uses_table_not_class_name’
./test/cases/…/…/…/activesupport/lib/active_support/testing/setup_and_teardown.rb:62:in
__send__' ./test/cases/../../../activesupport/lib/active_support/testing/setup_and_teardown.rb:62:in
run’
2076 tests, 6732 assertions, 1 failures, 0 errors
Is it better to interpret hash keys like :bars as table names or
associations? I thought associations. In my real life situation, the
table table is in a legacy schema, and the name is much more unwieldy.
I’d like to decouple my code from those unwieldy table names. In
some of the fancier join situations described in the association docs,
it might be slightly challenging
I get this with rails 2.3.4 and 2.3.5 with ruby 1.8.7 on Mac OS X. I
don’t have ruby 1.9 readily available to try it with rails 3.
The full test case is here:
Marcel