Skip to content
This repository

Allow for nesting of singleton belong_to's. #194

Closed
wants to merge 1 commit into from

7 participants

Douwe Maan Evgeniy Serykh Dmitry Lihachev Evgeny Lapin seongreen Joel Moss Romain Lalaut
Douwe Maan

In reference to issue #141.

Note that

class ThingAController < InheritedResources::Base
    belongs_to :thing_b, :singleton => true
end

used to mean there was only one ThingA (so resource_path == /thing_bs/123/thing_a), while it now means there is only one ThingB (so resource_path == /thing_b/thing_as/123)

To specify there is only one ThingA, you'll need

defaults :singleton => true
Douwe Maan Allow for nesting of singleton belong_to's.
Note that
    class ThingAController < InheritedResource::Base
        belongs_to :thing_b, :singleton => true
    end
used to mean there was only one ThingA (so resource_path == /thing_bs/123/thing_a), while it now means there is only one ThingB (so resource_path == /thing_b/thing_as/123)

To specify there is only one ThingA, you'll need
    defaults :singleton => true
cfb2d88
Dmitry Lihachev
lda commented October 28, 2012

:+1:

Joel Moss
Collaborator

Any chance you can update your PR please, so it merges cleanly? thx

Stephen Prater stephenprater referenced this pull request from a commit in stephenprater/inherited_resources February 15, 2013
update pr #194 to merge cleanly 3b649b8
Joel Moss joelmoss closed this March 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Jan 08, 2012
Douwe Maan Allow for nesting of singleton belong_to's.
Note that
    class ThingAController < InheritedResource::Base
        belongs_to :thing_b, :singleton => true
    end
used to mean there was only one ThingA (so resource_path == /thing_bs/123/thing_a), while it now means there is only one ThingB (so resource_path == /thing_b/thing_as/123)

To specify there is only one ThingA, you'll need
    defaults :singleton => true
cfb2d88
This page is out of date. Refresh to see the latest.
10  Gemfile.lock
@@ -31,14 +31,11 @@ GEM
31 31
       multi_json (~> 1.0)
32 32
     arel (2.2.1)
33 33
     builder (3.0.0)
34  
-    columnize (0.3.5)
35 34
     erubis (2.7.0)
36 35
     has_scope (0.5.1)
37 36
     hike (1.2.1)
38 37
     i18n (0.6.0)
39 38
     json (1.6.3)
40  
-    linecache (0.46)
41  
-      rbx-require-relative (> 0.0.4)
42 39
     mail (2.3.0)
43 40
       i18n (>= 0.4.0)
44 41
       mime-types (~> 1.16)
@@ -74,15 +71,9 @@ GEM
74 71
       rdoc (~> 3.4)
75 72
       thor (~> 0.14.6)
76 73
     rake (0.9.2.2)
77  
-    rbx-require-relative (0.0.5)
78 74
     rdoc (3.11)
79 75
       json (~> 1.4)
80 76
     responders (0.6.4)
81  
-    ruby-debug (0.10.4)
82  
-      columnize (>= 0.1)
83  
-      ruby-debug-base (~> 0.10.4.0)
84  
-    ruby-debug-base (0.10.4)
85  
-      linecache (>= 0.3)
86 77
     sprockets (2.1.2)
87 78
       hike (~> 1.2)
88 79
       rack (~> 1.0)
@@ -102,4 +93,3 @@ DEPENDENCIES
102 93
   mocha
103 94
   rails (= 3.1.2)
104 95
   responders (~> 0.6.0)
105  
-  ruby-debug
18  lib/inherited_resources/belongs_to_helpers.rb
@@ -74,13 +74,21 @@ def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
74 74
         instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
75 75
         return instantiated_object if instantiated_object
76 76
 
77  
-        parent = if chain
78  
-          chain.send(parent_config[:collection_name])
  77
+        if parent_config[:singleton]
  78
+          parent = if chain
  79
+            chain.send(parent_config[:instance_name])
  80
+          else
  81
+            nil
  82
+          end
79 83
         else
80  
-          parent_config[:parent_class]
81  
-        end
  84
+          parent = if chain
  85
+            chain.send(parent_config[:collection_name])
  86
+          else
  87
+            parent_config[:parent_class]
  88
+          end
82 89
 
83  
-        parent = parent.send(parent_config[:finder], params[parent_config[:param]])
  90
+          parent = parent.send(parent_config[:finder], params[parent_config[:param]])
  91
+        end
84 92
 
85 93
         instance_variable_set("@#{parent_config[:instance_name]}", parent)
86 94
       end
3  lib/inherited_resources/class_methods.rb
@@ -145,13 +145,11 @@ def belongs_to(*symbols, &block)
145 145
 
146 146
         optional    = options.delete(:optional)
147 147
         shallow     = options.delete(:shallow)
148  
-        singleton   = options.delete(:singleton)
149 148
         polymorphic = options.delete(:polymorphic)
150 149
         finder      = options.delete(:finder)
151 150
 
152 151
         include BelongsToHelpers if self.parents_symbols.empty?
153 152
 
154  
-        acts_as_singleton!   if singleton
155 153
         acts_as_polymorphic! if polymorphic || optional
156 154
         acts_as_shallow!     if shallow
157 155
 
@@ -181,6 +179,7 @@ def belongs_to(*symbols, &block)
181 179
             nil
182 180
           end
183 181
 
  182
+          config[:singleton]       = options.delete(:singleton) || false
184 183
           config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
185 184
           config[:instance_name]   = options.delete(:instance_name) || symbol
186 185
           config[:param]           = options.delete(:param) || :"#{symbol}_id"
10  lib/inherited_resources/url_helpers.rb
@@ -68,8 +68,14 @@ def create_resources_url_helpers!
68 68
           resource_ivars << :parent
69 69
         else
70 70
           config = self.resources_configuration[symbol]
71  
-          resource_segments << config[:route_name]
72  
-          resource_ivars    << :"@#{config[:instance_name]}"
  71
+          if config[:singleton] && polymorphic
  72
+            resource_ivars << config[:instance_name].inspect
  73
+          else
  74
+            resource_segments << config[:route_name]
  75
+          end
  76
+          if !config[:singleton]
  77
+            resource_ivars    << :"@#{config[:instance_name]}"
  78
+          end
73 79
         end
74 80
       end
75 81
 
3  test/singleton_test.rb
@@ -13,7 +13,8 @@ class Manager
13 13
 end
14 14
 
15 15
 class ManagersController < InheritedResources::Base
16  
-  belongs_to :store, :singleton => true
  16
+  defaults :singleton => true
  17
+  belongs_to :store
17 18
 end
18 19
 
19 20
 class SingletonTest < ActionController::TestCase
139  test/url_helpers_test.rb
@@ -45,7 +45,21 @@ class ChairsController < InheritedResources::Base
45 45
 end
46 46
 
47 47
 class OwnersController < InheritedResources::Base
48  
-  singleton_belongs_to :house
  48
+  defaults :singleton => true
  49
+  
  50
+  belongs_to :house
  51
+end
  52
+
  53
+class Fireplace
  54
+  extend ActiveModel::Naming
  55
+end
  56
+class Flame
  57
+  extend ActiveModel::Naming
  58
+end
  59
+class FlamesController < InheritedResources::Base
  60
+  belongs_to :house do
  61
+    belongs_to :fireplace, :singleton => true
  62
+  end
49 63
 end
50 64
 
51 65
 class Bed
@@ -80,6 +94,23 @@ class DishesController < InheritedResources::Base
80 94
   end
81 95
 end
82 96
 
  97
+class Dishwasher
  98
+  extend ActiveModel::Naming
  99
+end
  100
+class Fork
  101
+  extend ActiveModel::Naming
  102
+end
  103
+class Spot
  104
+  extend ActiveModel::Naming
  105
+end
  106
+class SpotsController < InheritedResources::Base
  107
+  belongs_to :house do
  108
+    belongs_to :dishwasher, :singleton => true do
  109
+      polymorphic_belongs_to :dish, :fork
  110
+    end
  111
+  end
  112
+end
  113
+
83 114
 class Center
84 115
   extend ActiveModel::Naming
85 116
 end
@@ -244,6 +275,38 @@ def test_url_helpers_on_simple_inherited_singleton_resource
244 275
       controller.send("resource_#{path_or_url}", :arg, :page => 1)
245 276
     end
246 277
   end
  278
+  
  279
+  def test_url_helpers_on_singleton_belongs_to
  280
+    controller = FlamesController.new
  281
+    controller.instance_variable_set('@house', :house)
  282
+    controller.instance_variable_set('@fireplace', :fireplace)
  283
+    controller.instance_variable_set('@flame', :flame)
  284
+
  285
+    [:url, :path].each do |path_or_url|
  286
+      controller.expects("house_fireplace_flames_#{path_or_url}").with(:house, {}).once
  287
+      controller.send("collection_#{path_or_url}")
  288
+
  289
+      controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
  290
+      controller.send("resource_#{path_or_url}")
  291
+
  292
+      controller.expects("new_house_fireplace_flame_#{path_or_url}").with(:house, {}).once
  293
+      controller.send("new_resource_#{path_or_url}")
  294
+
  295
+      controller.expects("edit_house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
  296
+      controller.send("edit_resource_#{path_or_url}")
  297
+
  298
+      controller.expects("house_fireplace_#{path_or_url}").with(:house, {}).once
  299
+      controller.send("parent_#{path_or_url}")
  300
+
  301
+      controller.expects("edit_house_fireplace_#{path_or_url}").with(:house, {}).once
  302
+      controller.send("edit_parent_#{path_or_url}")
  303
+
  304
+      # With options
  305
+      # Also tests that argument sent are not used
  306
+      controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :arg, :page => 1).once
  307
+      controller.send("resource_#{path_or_url}", :arg, :page => 1)
  308
+    end
  309
+  end
247 310
 
248 311
   def test_url_helpers_on_belongs_to
249 312
     controller = TablesController.new
@@ -396,6 +459,80 @@ def test_url_helpers_on_singletons_with_belongs_to
396 459
       controller.send("resource_#{path_or_url}", :arg, :page => 1)
397 460
     end
398 461
   end
  462
+  
  463
+  def test_url_helpers_on_nested_polymorphic_belongs_to
  464
+    house = House.new
  465
+    table = Table.new
  466
+    dish  = Dish.new
  467
+
  468
+    new_dish = Dish.new
  469
+    Dish.stubs(:new).returns(new_dish)
  470
+    new_dish.stubs(:persisted?).returns(false)
  471
+
  472
+    controller = DishesController.new
  473
+    controller.instance_variable_set('@parent_type', :table)
  474
+    controller.instance_variable_set('@house', house)
  475
+    controller.instance_variable_set('@table', table)
  476
+    controller.instance_variable_set('@dish', dish)
  477
+
  478
+    [:url, :path].each do |path_or_url|
  479
+      mock_polymorphic(controller, "house_table_dishes_#{path_or_url}").with(house, table).once
  480
+      controller.send("collection_#{path_or_url}")
  481
+
  482
+      mock_polymorphic(controller, "house_table_dish_#{path_or_url}").with(house, table, dish).once
  483
+      controller.send("resource_#{path_or_url}")
  484
+
  485
+      mock_polymorphic(controller, "new_house_table_dish_#{path_or_url}").with(house, table).once
  486
+      controller.send("new_resource_#{path_or_url}")
  487
+
  488
+      mock_polymorphic(controller, "edit_house_table_dish_#{path_or_url}").with(house, table, dish).once
  489
+      controller.send("edit_resource_#{path_or_url}")
  490
+
  491
+      mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once
  492
+      controller.send("parent_#{path_or_url}")
  493
+
  494
+      mock_polymorphic(controller, "edit_house_table_#{path_or_url}").with(house, table).once
  495
+      controller.send("edit_parent_#{path_or_url}")
  496
+    end
  497
+  end
  498
+
  499
+  def test_url_helpers_on_singleton_and_polymorphic_belongs_to
  500
+    house = House.new
  501
+    dishwasher = Dishwasher.new
  502
+    fork = Fork.new
  503
+    spot = Spot.new
  504
+
  505
+    new_spot = Spot.new
  506
+    Spot.stubs(:new).returns(new_spot)
  507
+    new_spot.stubs(:persisted?).returns(false)
  508
+    
  509
+    controller = SpotsController.new
  510
+    controller.instance_variable_set('@parent_type', :fork)
  511
+    controller.instance_variable_set('@house', house)
  512
+    controller.instance_variable_set('@dishwasher', dishwasher)
  513
+    controller.instance_variable_set('@fork', fork)
  514
+    controller.instance_variable_set('@spot', spot)
  515
+
  516
+    [:url, :path].each do |path_or_url|
  517
+      mock_polymorphic(controller, "house_dishwasher_fork_spots_#{path_or_url}").with(house, fork).once
  518
+      controller.send("collection_#{path_or_url}")
  519
+
  520
+      mock_polymorphic(controller, "house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
  521
+      controller.send("resource_#{path_or_url}")
  522
+
  523
+      mock_polymorphic(controller, "new_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork).once
  524
+      controller.send("new_resource_#{path_or_url}")
  525
+
  526
+      mock_polymorphic(controller, "edit_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
  527
+      controller.send("edit_resource_#{path_or_url}")
  528
+
  529
+      mock_polymorphic(controller, "house_dishwasher_fork_#{path_or_url}").with(house, fork).once
  530
+      controller.send("parent_#{path_or_url}")
  531
+
  532
+      mock_polymorphic(controller, "edit_house_dishwasher_fork_#{path_or_url}").with(house, fork).once
  533
+      controller.send("edit_parent_#{path_or_url}")
  534
+    end
  535
+  end
399 536
 
400 537
   def test_url_helpers_on_polymorphic_belongs_to
401 538
     house = House.new
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.