Skip to content

Commit 208a24f

Browse files
committed
Support through_association with singleton.
Given a load declaration like: ```ruby load_resource :order load_resource through: :address, through_association: :custom_address, singleton: true ``` The `:through_assocation` option wasn't being respected in the `:singleton` branch, thus falling back to calling `find`, but odds are you wouldn't have an ID given it was a singleton, thus leading to an error. Now it uses the `:through_association` before falling back to the `name`. Fixes #604.
1 parent 1100093 commit 208a24f

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Unreleased
2+
3+
* [#878](https://github.com/CanCanCommunity/cancancan/pull/878): Support `through_association` with `singleton`. ([@cgunther][])
4+
15
## 3.6.0
26

37
* [#849](https://github.com/CanCanCommunity/cancancan/pull/849): Update tests matrix. ([@coorasse][])
@@ -716,3 +720,4 @@ Please read the [guide on migrating from CanCanCan 2.x to 3.0](https://github.co
716720
[@MrChoclate]: https://github.com/MrChoclate
717721
[@pandermatt]: https://github.com/pandermatt
718722
[@kalsan]: https://github.com/kalsan
723+
[@cgunther]: https://github.com/cgunther

lib/cancan/controller_resource_finder.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ module ControllerResourceFinder
55
protected
66

77
def find_resource
8-
if @options[:singleton] && parent_resource.respond_to?(name)
9-
parent_resource.send(name)
8+
singleton_association_name = @options[:through_association] || name
9+
if @options[:singleton] && parent_resource.respond_to?(singleton_association_name)
10+
parent_resource.send(singleton_association_name)
1011
elsif @options[:find_by]
1112
find_resource_using_find_by
1213
else

spec/cancan/controller_resource_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,24 @@ class Dashboard; end
430430
expect(controller.instance_variable_get(:@model)).to eq(model)
431431
end
432432

433+
it 'finds record through has_one association with :through_association and :singleton options' do
434+
params[:id] = nil
435+
436+
model = Model.new
437+
438+
category = double(custom_model: model)
439+
controller.instance_variable_set(:@category, category)
440+
441+
resource = CanCan::ControllerResource.new(
442+
controller,
443+
through: :category,
444+
through_association: :custom_model,
445+
singleton: true,
446+
)
447+
resource.load_resource
448+
expect(controller.instance_variable_get(:@model)).to eq(model)
449+
end
450+
433451
it 'loads the model using a custom class' do
434452
model = Model.new
435453
allow(Model).to receive(:find).with('123') { model }

0 commit comments

Comments
 (0)