Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

find_by_* method declared on an a hmt association class is ignored #10304

Closed
dhh opened this Issue · 4 comments

3 participants

David Heinemeier Hansson Neeraj Singh Jon Leighton
David Heinemeier Hansson
Owner
diff --git a/activerecord/test/cases/deprecated_dynamic_methods_test.rb b/activerecord/test/cases/deprecated_dynamic_methods_test.rb
index 8e842d8..a6b56c2 100644
--- a/activerecord/test/cases/deprecated_dynamic_methods_test.rb
+++ b/activerecord/test/cases/deprecated_dynamic_methods_test.rb
@@ -413,6 +413,10 @@ class DeprecatedDynamicMethodsTest < ActiveRecord::TestCase
     assert_equal person, person.readers.first.person
   end

+  def test_find_by_custom_finder_on_association_class
+    assert_equal [], Author.first.comments.find_by_anything!
+  end
+
   def test_find_or_initialize
     the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
     assert_equal companies(:first_firm).id, the_client.firm_id
diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb
index ede5fbd..75cd984 100644
--- a/activerecord/test/models/comment.rb
+++ b/activerecord/test/models/comment.rb
@@ -26,6 +26,11 @@ class Comment < ActiveRecord::Base
     all
   end
   scope :all_as_scope, -> { all }
+
+  
+  def self.find_by_anything!
+    all
+  end
 end

 class SpecialComment < Comment

Produces this failure:


DeprecatedDynamicMethodsTest#test_find_by_custom_finder_on_association_class:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: comments.anything: SELECT  "comments".* FROM "comments" INNER JOIN "posts" ON "comments"."post_id" = "posts"."id" WHERE "posts"."author_id" = ? AND "comments"."anything" IS NULL LIMIT 1
    /Users/david/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `initialize'
    /Users/david/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `new'
    /Users/david/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `prepare'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb:303:in `block in exec_query'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:425:in `block in log'
    /Users/david/Code/rails/activesupport/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:420:in `log'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb:292:in `exec_query'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb:504:in `select'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:24:in `select_all'
    /Users/david/Code/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
    /Users/david/Code/rails/activerecord/lib/active_record/querying.rb:36:in `find_by_sql'
    /Users/david/Code/rails/activerecord/lib/active_record/relation.rb:561:in `exec_queries'
    /Users/david/Code/rails/activerecord/lib/active_record/relation.rb:447:in `load'
    /Users/david/Code/rails/activerecord/lib/active_record/relation.rb:196:in `to_a'
    /Users/david/Code/rails/activerecord/lib/active_record/relation/finder_methods.rb:315:in `find_take'
    /Users/david/Code/rails/activerecord/lib/active_record/relation/finder_methods.rb:65:in `take'
    /Users/david/Code/rails/activerecord/lib/active_record/relation/finder_methods.rb:71:in `take!'
    /Users/david/Code/rails/activerecord/lib/active_record/relation/finder_methods.rb:54:in `find_by!'
    /Users/david/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/activerecord-deprecated_finders-1.0.1/lib/active_record/deprecated_finders/collection_proxy.rb:10:in `method_missing'
    test/cases/deprecated_dynamic_methods_test.rb:417:in `test_find_by_custom_finder_on_association_class'
Jon Leighton jonleighton was assigned
Neeraj Singh
Collaborator

It is caused by this commit rails/activerecord-deprecated_finders@f97e977 .

If the base model is invoked first then find_or_create_by(name: 'Tim1') is not creating the association record.

However by invoking the proxy first this issue is caused.

David Heinemeier Hansson
Owner

Do you have an idea of how we can fix this?

Neeraj Singh
Collaborator

@dhh The only thing I could think of is that if the method name is find_or_create_by then invoke the proxy first so that association record could get created. Otherwise act on base klass.

However that is a hack too. Because ideally if the base class has a method

def self.find_or_create_by(*args)
end

then this method should be executed.

@jonleighton any thoughts on how this case should be handled.

Neeraj Singh neerajdotname referenced this issue in rails/activerecord-deprecated_finders
Merged

better fix for #9994 #14

Neeraj Singh
Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.