Skip to content

Commit

Permalink
Prevent normalization of polymorphic association (#592)
Browse files Browse the repository at this point in the history
Polymorphic associations have no klass names, so those should be not
normalized. Fixes #588
  • Loading branch information
eloyesp authored and coorasse committed Aug 22, 2019
1 parent 24f3b54 commit 2236e25
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* [#592](https://github.com/CanCanCommunity/cancancan/pull/592): Prevent normalization of through polymorphic associations.([@eloyesp][])

## 3.0.1

* [#583](https://github.com/CanCanCommunity/cancancan/pull/583): Fix regression when using a method reference block. ([@coorasse][])
Expand Down Expand Up @@ -643,3 +645,4 @@ Please read the [guide on migrating from CanCanCan 2.x to 3.0](https://github.co
[@andrew-aladev]: https://github.com/andrew-aladev
[@phaedryx]: https://github.com/phaedryx
[@kaspernj]: https://github.com/kaspernj
[@eloyesp]: https://github.com/eloyesp
6 changes: 5 additions & 1 deletion lib/cancan/model_adapters/conditions_normalizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@ def calculate_result_hash(model_class, key, value)
raise WrongAssociationName, "Association '#{key}' not defined in model '#{model_class.name}'"
end

if reflection.options[:through].present?
if normalizable_association? reflection
key = reflection.options[:through]
value = { reflection.source_reflection_name => value }
reflection = model_class.reflect_on_association(key)
end

{ key => normalize_conditions(reflection.klass.name.constantize, value) }
end

def normalizable_association?(reflection)
reflection.options[:through].present? && !reflection.options[:source_type].present?
end
end
end
end
Expand Down
25 changes: 25 additions & 0 deletions spec/cancan/model_adapters/conditions_normalizer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@
t.integer :user_id
t.integer :article_id
end

create_table(:attachments) do |t|
t.references :record, polymorphic: true
t.integer :blob_id
end

create_table(:blob) do |t|
end
end

class Article < ActiveRecord::Base
has_many :spread_comments
has_many :comments, through: :spread_comments
has_many :mentions
has_many :mentioned_users, through: :mentions, source: :user
has_many :attachments, as: :record
end

class Comment < ActiveRecord::Base
Expand All @@ -53,6 +62,16 @@ class User < ActiveRecord::Base
has_many :mentions
has_many :mentioned_articles, through: :mentions, source: :article
end

class Attachment < ActiveRecord::Base
belongs_to :record, polymorphic: true
belongs_to :blob
end

class Blob < ActiveRecord::Base
has_many :attachments
has_many :articles, through: :attachments, source: :record, source_type: 'Article'
end
end

it 'simplifies has_many through associations' do
Expand All @@ -61,6 +80,12 @@ class User < ActiveRecord::Base
expect(rule.conditions).to eq(spread_comments: { article: { mentions: { user: { name: 'pippo' } } } })
end

it 'does not simplifies has_many through polymorphic associations' do
rule = CanCan::Rule.new(true, :read, Blob, articles: { id: 11 })
CanCan::ModelAdapters::ConditionsNormalizer.normalize(Blob, [rule])
expect(rule.conditions).to eq(articles: { id: 11 })
end

it 'normalizes the has_one through associations' do
class Supplier < ActiveRecord::Base
has_one :accountant
Expand Down

0 comments on commit 2236e25

Please sign in to comment.