Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

AssociationCollection#create_by_*, find_or_create_by_* work properly …

…now. [#1108 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
commit 3f563f169612ec340816f0a549fe9db7ff95c238 1 parent d7c2e52
Aaron Patterson authored June 29, 2010 jeremy committed June 29, 2010
11  activerecord/lib/active_record/associations/association_collection.rb
@@ -409,6 +409,17 @@ def load_target
409 409
         end
410 410
 
411 411
         def method_missing(method, *args)
  412
+          case method.to_s
  413
+          when 'find_or_create'
  414
+            return find(:first, :conditions => args.first) || create(args.first)
  415
+          when /^find_or_create_by_(.*)$/
  416
+            rest = $1
  417
+            return  send("find_by_#{rest}", *args) ||
  418
+                    method_missing("create_by_#{rest}", *args)
  419
+          when /^create_by_(.*)$/
  420
+            return create Hash[$1.split('_and_').zip(args)]
  421
+          end
  422
+
412 423
           if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
413 424
             if block_given?
414 425
               super { |*block_args| yield(*block_args) }
62  activerecord/test/cases/associations/has_many_associations_test.rb
@@ -21,6 +21,68 @@ def setup
21 21
     Client.destroyed_client_ids.clear
22 22
   end
23 23
 
  24
+  def test_create_by
  25
+    person = Person.create! :first_name => 'tenderlove'
  26
+    post   = Post.find :first
  27
+
  28
+    assert_equal [], person.readers
  29
+    assert_nil person.readers.find_by_post_id post.id
  30
+
  31
+    reader = person.readers.create_by_post_id post.id
  32
+
  33
+    assert_equal 1, person.readers.count
  34
+    assert_equal 1, person.readers.length
  35
+    assert_equal post, person.readers.first.post
  36
+    assert_equal person, person.readers.first.person
  37
+  end
  38
+
  39
+  def test_create_by_multi
  40
+    person = Person.create! :first_name => 'tenderlove'
  41
+    post   = Post.find :first
  42
+
  43
+    assert_equal [], person.readers
  44
+
  45
+    reader = person.readers.create_by_post_id_and_skimmer post.id, false
  46
+
  47
+    assert_equal 1, person.readers.count
  48
+    assert_equal 1, person.readers.length
  49
+    assert_equal post, person.readers.first.post
  50
+    assert_equal person, person.readers.first.person
  51
+  end
  52
+
  53
+  def test_find_or_create_by
  54
+    person = Person.create! :first_name => 'tenderlove'
  55
+    post   = Post.find :first
  56
+
  57
+    assert_equal [], person.readers
  58
+    assert_nil person.readers.find_by_post_id post.id
  59
+
  60
+    reader = person.readers.find_or_create_by_post_id post.id
  61
+
  62
+    assert_equal 1, person.readers.count
  63
+    assert_equal 1, person.readers.length
  64
+    assert_equal post, person.readers.first.post
  65
+    assert_equal person, person.readers.first.person
  66
+  end
  67
+
  68
+  def test_find_or_create
  69
+    person = Person.create! :first_name => 'tenderlove'
  70
+    post   = Post.find :first
  71
+
  72
+    assert_equal [], person.readers
  73
+    assert_nil person.readers.find(:first, :conditions => {
  74
+      :post_id => post.id
  75
+    })
  76
+
  77
+    reader = person.readers.find_or_create :post_id => post.id
  78
+
  79
+    assert_equal 1, person.readers.count
  80
+    assert_equal 1, person.readers.length
  81
+    assert_equal post, person.readers.first.post
  82
+    assert_equal person, person.readers.first.person
  83
+  end
  84
+
  85
+
24 86
   def force_signal37_to_load_all_clients_of_firm
25 87
     companies(:first_firm).clients_of_firm.each {|f| }
26 88
   end

0 notes on commit 3f563f1

Please sign in to comment.
Something went wrong with that request. Please try again.