Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow for nesting of singleton belong_to's. #194

Closed
wants to merge 1 commit into from

7 participants

@DouweM

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
@DouweM DouweM 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
@joelmoss

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

@stephenprater stephenprater referenced this pull request from a commit in stephenprater/inherited_resources
Stephen Prater (@laptop) update pr #194 to merge cleanly 3b649b8
@stephenprater stephenprater referenced this pull request
Merged

Pull request #194 #258

@joelmoss joelmoss closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 8, 2012
  1. @DouweM

    Allow for nesting of singleton belong_to's.

    DouweM authored
    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
This page is out of date. Refresh to see the latest.
View
10 Gemfile.lock
@@ -31,14 +31,11 @@ GEM
multi_json (~> 1.0)
arel (2.2.1)
builder (3.0.0)
- columnize (0.3.5)
erubis (2.7.0)
has_scope (0.5.1)
hike (1.2.1)
i18n (0.6.0)
json (1.6.3)
- linecache (0.46)
- rbx-require-relative (> 0.0.4)
mail (2.3.0)
i18n (>= 0.4.0)
mime-types (~> 1.16)
@@ -74,15 +71,9 @@ GEM
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
- rbx-require-relative (0.0.5)
rdoc (3.11)
json (~> 1.4)
responders (0.6.4)
- ruby-debug (0.10.4)
- columnize (>= 0.1)
- ruby-debug-base (~> 0.10.4.0)
- ruby-debug-base (0.10.4)
- linecache (>= 0.3)
sprockets (2.1.2)
hike (~> 1.2)
rack (~> 1.0)
@@ -102,4 +93,3 @@ DEPENDENCIES
mocha
rails (= 3.1.2)
responders (~> 0.6.0)
- ruby-debug
View
18 lib/inherited_resources/belongs_to_helpers.rb
@@ -74,13 +74,21 @@ def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
return instantiated_object if instantiated_object
- parent = if chain
- chain.send(parent_config[:collection_name])
+ if parent_config[:singleton]
+ parent = if chain
+ chain.send(parent_config[:instance_name])
+ else
+ nil
+ end
else
- parent_config[:parent_class]
- end
+ parent = if chain
+ chain.send(parent_config[:collection_name])
+ else
+ parent_config[:parent_class]
+ end
- parent = parent.send(parent_config[:finder], params[parent_config[:param]])
+ parent = parent.send(parent_config[:finder], params[parent_config[:param]])
+ end
instance_variable_set("@#{parent_config[:instance_name]}", parent)
end
View
3  lib/inherited_resources/class_methods.rb
@@ -145,13 +145,11 @@ def belongs_to(*symbols, &block)
optional = options.delete(:optional)
shallow = options.delete(:shallow)
- singleton = options.delete(:singleton)
polymorphic = options.delete(:polymorphic)
finder = options.delete(:finder)
include BelongsToHelpers if self.parents_symbols.empty?
- acts_as_singleton! if singleton
acts_as_polymorphic! if polymorphic || optional
acts_as_shallow! if shallow
@@ -181,6 +179,7 @@ def belongs_to(*symbols, &block)
nil
end
+ config[:singleton] = options.delete(:singleton) || false
config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
config[:instance_name] = options.delete(:instance_name) || symbol
config[:param] = options.delete(:param) || :"#{symbol}_id"
View
10 lib/inherited_resources/url_helpers.rb
@@ -68,8 +68,14 @@ def create_resources_url_helpers!
resource_ivars << :parent
else
config = self.resources_configuration[symbol]
- resource_segments << config[:route_name]
- resource_ivars << :"@#{config[:instance_name]}"
+ if config[:singleton] && polymorphic
+ resource_ivars << config[:instance_name].inspect
+ else
+ resource_segments << config[:route_name]
+ end
+ if !config[:singleton]
+ resource_ivars << :"@#{config[:instance_name]}"
+ end
end
end
View
3  test/singleton_test.rb
@@ -13,7 +13,8 @@ class Manager
end
class ManagersController < InheritedResources::Base
- belongs_to :store, :singleton => true
+ defaults :singleton => true
+ belongs_to :store
end
class SingletonTest < ActionController::TestCase
View
139 test/url_helpers_test.rb
@@ -45,7 +45,21 @@ class ChairsController < InheritedResources::Base
end
class OwnersController < InheritedResources::Base
- singleton_belongs_to :house
+ defaults :singleton => true
+
+ belongs_to :house
+end
+
+class Fireplace
+ extend ActiveModel::Naming
+end
+class Flame
+ extend ActiveModel::Naming
+end
+class FlamesController < InheritedResources::Base
+ belongs_to :house do
+ belongs_to :fireplace, :singleton => true
+ end
end
class Bed
@@ -80,6 +94,23 @@ class DishesController < InheritedResources::Base
end
end
+class Dishwasher
+ extend ActiveModel::Naming
+end
+class Fork
+ extend ActiveModel::Naming
+end
+class Spot
+ extend ActiveModel::Naming
+end
+class SpotsController < InheritedResources::Base
+ belongs_to :house do
+ belongs_to :dishwasher, :singleton => true do
+ polymorphic_belongs_to :dish, :fork
+ end
+ end
+end
+
class Center
extend ActiveModel::Naming
end
@@ -244,6 +275,38 @@ def test_url_helpers_on_simple_inherited_singleton_resource
controller.send("resource_#{path_or_url}", :arg, :page => 1)
end
end
+
+ def test_url_helpers_on_singleton_belongs_to
+ controller = FlamesController.new
+ controller.instance_variable_set('@house', :house)
+ controller.instance_variable_set('@fireplace', :fireplace)
+ controller.instance_variable_set('@flame', :flame)
+
+ [:url, :path].each do |path_or_url|
+ controller.expects("house_fireplace_flames_#{path_or_url}").with(:house, {}).once
+ controller.send("collection_#{path_or_url}")
+
+ controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
+ controller.send("resource_#{path_or_url}")
+
+ controller.expects("new_house_fireplace_flame_#{path_or_url}").with(:house, {}).once
+ controller.send("new_resource_#{path_or_url}")
+
+ controller.expects("edit_house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
+ controller.send("edit_resource_#{path_or_url}")
+
+ controller.expects("house_fireplace_#{path_or_url}").with(:house, {}).once
+ controller.send("parent_#{path_or_url}")
+
+ controller.expects("edit_house_fireplace_#{path_or_url}").with(:house, {}).once
+ controller.send("edit_parent_#{path_or_url}")
+
+ # With options
+ # Also tests that argument sent are not used
+ controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :arg, :page => 1).once
+ controller.send("resource_#{path_or_url}", :arg, :page => 1)
+ end
+ end
def test_url_helpers_on_belongs_to
controller = TablesController.new
@@ -396,6 +459,80 @@ def test_url_helpers_on_singletons_with_belongs_to
controller.send("resource_#{path_or_url}", :arg, :page => 1)
end
end
+
+ def test_url_helpers_on_nested_polymorphic_belongs_to
+ house = House.new
+ table = Table.new
+ dish = Dish.new
+
+ new_dish = Dish.new
+ Dish.stubs(:new).returns(new_dish)
+ new_dish.stubs(:persisted?).returns(false)
+
+ controller = DishesController.new
+ controller.instance_variable_set('@parent_type', :table)
+ controller.instance_variable_set('@house', house)
+ controller.instance_variable_set('@table', table)
+ controller.instance_variable_set('@dish', dish)
+
+ [:url, :path].each do |path_or_url|
+ mock_polymorphic(controller, "house_table_dishes_#{path_or_url}").with(house, table).once
+ controller.send("collection_#{path_or_url}")
+
+ mock_polymorphic(controller, "house_table_dish_#{path_or_url}").with(house, table, dish).once
+ controller.send("resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "new_house_table_dish_#{path_or_url}").with(house, table).once
+ controller.send("new_resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "edit_house_table_dish_#{path_or_url}").with(house, table, dish).once
+ controller.send("edit_resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once
+ controller.send("parent_#{path_or_url}")
+
+ mock_polymorphic(controller, "edit_house_table_#{path_or_url}").with(house, table).once
+ controller.send("edit_parent_#{path_or_url}")
+ end
+ end
+
+ def test_url_helpers_on_singleton_and_polymorphic_belongs_to
+ house = House.new
+ dishwasher = Dishwasher.new
+ fork = Fork.new
+ spot = Spot.new
+
+ new_spot = Spot.new
+ Spot.stubs(:new).returns(new_spot)
+ new_spot.stubs(:persisted?).returns(false)
+
+ controller = SpotsController.new
+ controller.instance_variable_set('@parent_type', :fork)
+ controller.instance_variable_set('@house', house)
+ controller.instance_variable_set('@dishwasher', dishwasher)
+ controller.instance_variable_set('@fork', fork)
+ controller.instance_variable_set('@spot', spot)
+
+ [:url, :path].each do |path_or_url|
+ mock_polymorphic(controller, "house_dishwasher_fork_spots_#{path_or_url}").with(house, fork).once
+ controller.send("collection_#{path_or_url}")
+
+ mock_polymorphic(controller, "house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
+ controller.send("resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "new_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork).once
+ controller.send("new_resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "edit_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
+ controller.send("edit_resource_#{path_or_url}")
+
+ mock_polymorphic(controller, "house_dishwasher_fork_#{path_or_url}").with(house, fork).once
+ controller.send("parent_#{path_or_url}")
+
+ mock_polymorphic(controller, "edit_house_dishwasher_fork_#{path_or_url}").with(house, fork).once
+ controller.send("edit_parent_#{path_or_url}")
+ end
+ end
def test_url_helpers_on_polymorphic_belongs_to
house = House.new
Something went wrong with that request. Please try again.