diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0aa21..672a0c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added `Pragma::Decorator::Error`, which was previously in [pragma](https://github.com/pragmarb/pragma) +- Added `Pragma::Decorator::Association::Expander`, which was previously in + [pragma](https://github.com/pragmarb/pragma) ### Changed diff --git a/lib/pragma/decorator/association/expander.rb b/lib/pragma/decorator/association/expander.rb new file mode 100644 index 0000000..efeb2a9 --- /dev/null +++ b/lib/pragma/decorator/association/expander.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Pragma + module Decorator + module Association + module Expander + include Adaptor::Loader + register ActiveRecord, Poro + end + end + end +end diff --git a/lib/pragma/decorator/association/expander/active_record.rb b/lib/pragma/decorator/association/expander/active_record.rb new file mode 100644 index 0000000..9e55e22 --- /dev/null +++ b/lib/pragma/decorator/association/expander/active_record.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Pragma + module Decorator + module Association + module Expander + class ActiveRecord < Base + class << self + def supports?(relation) + defined?(::ActiveRecord::Relation) && relation.is_a?(::ActiveRecord::Relation) + end + end + + def include_associations(expands) + relation.includes(validate_associations( + relation.model, + destruct_associations(expands) + )) + end + + private + + def destruct_associations(expands) + associations = {} + + expands.each do |expand| + expand.split('.').inject(associations) do |accumulator, association| + accumulator[association] ||= {} + end + end + + associations + end + + def validate_associations(model, associations) + Hash[associations.map do |(key, value)| + reflection = model.reflect_on_association(key.to_sym) + reflection ? [key, validate_associations(reflection.klass, value)] : [false, false] + end.select { |_, v| v }] + end + end + end + end + end +end diff --git a/lib/pragma/decorator/association/expander/base.rb b/lib/pragma/decorator/association/expander/base.rb new file mode 100644 index 0000000..d78aa0a --- /dev/null +++ b/lib/pragma/decorator/association/expander/base.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Pragma + module Decorator + module Association + module Expander + class Base + attr_reader :relation + + class << self + def supports?(_relation) + fail NotImplementedError + end + end + + def initialize(relation) + @relation = relation + end + + def include_associations(_expands) + fail NotImplementedError + end + end + end + end + end +end diff --git a/lib/pragma/decorator/association/expander/poro.rb b/lib/pragma/decorator/association/expander/poro.rb new file mode 100644 index 0000000..583ee8b --- /dev/null +++ b/lib/pragma/decorator/association/expander/poro.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Pragma + module Decorator + module Association + module Expander + class Poro < Base + class << self + def supports?(_relation) + true + end + end + + def include_associations(_expands) + relation + end + end + end + end + end +end