Skip to content

Commit aad91da

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 aad91da

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

CHANGELOG.md

+4
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][])

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

+13
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,19 @@ 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(controller, through: :category, through_association: :custom_model, singleton: true)
442+
resource.load_resource
443+
expect(controller.instance_variable_get(:@model)).to eq(model)
444+
end
445+
433446
it 'loads the model using a custom class' do
434447
model = Model.new
435448
allow(Model).to receive(:find).with('123') { model }

0 commit comments

Comments
 (0)