lib/heimdallr/proxy/record.rb in heimdallr-1.0.3 vs lib/heimdallr/proxy/record.rb in heimdallr-1.0.4

- old
+ new

@@ -14,13 +14,14 @@ # # @param context security context # @param object proxified record # @option options [Boolean] implicit proxy type def initialize(context, record, options={}) - @context, @record, @options = context, record, options + @context, @record, @options = context, record, options.dup @restrictions = @record.class.restrictions(context, record) + @eager_loaded = @options.delete(:eager_loaded) || {} end # @method decrement(field, by=1) # @macro [new] delegate # Delegates to the corresponding method of underlying object. @@ -38,10 +39,22 @@ # @macro delegate # This method does not modify any fields except for the timestamp itself # and thus is not considered as a potential security threat. delegate :touch, :to => :@record + # @method model_name + # @macro delegate + delegate :model_name, :to => :@record + + # @method to_key + # @macro delegate + delegate :to_key, :to => :@record + + # @method to_param + # @macro delegate + delegate :to_param, :to => :@record + # A proxy for +attributes+ method which removes all attributes # without +:view+ permission. def attributes @record.attributes.tap do |attributes| attributes.keys.each do |key| @@ -174,20 +187,32 @@ else normalized_method = method suffix = nil end - if (defined?(ActiveRecord) && @record.is_a?(ActiveRecord::Reflection) && + if (@record.is_a?(ActiveRecord::Reflection) && association = @record.class.reflect_on_association(method)) || (!@record.class.heimdallr_relations.nil? && @record.class.heimdallr_relations.include?(normalized_method)) referenced = @record.send(method, *args) if referenced.nil? nil elsif referenced.respond_to? :restrict - referenced.restrict(@context, @options) + if @eager_loaded.include?(method) + options = @options.merge(eager_loaded: @eager_loaded[method]) + else + options = @options + end + + if association.collection? && @eager_loaded.include?(method) + # Don't re-restrict eagerly loaded collections to not + # discard preloaded data. + Proxy::Collection.new(@context, referenced, options) + else + referenced.restrict(@context, @options) + end elsif Heimdallr.allow_insecure_associations referenced else raise Heimdallr::InsecureOperationError, "Attempt to fetch insecure association #{method}. Try #insecure" @@ -259,9 +284,14 @@ context: @context, record: @record, options: @options, restrictions: @restrictions, }.merge(@restrictions.reflection) + end + + def visible? + scope = @restrictions.request_scope(:fetch) + scope.where({ @record.class.primary_key => @record.to_key }).any? end def creatable? @restrictions.can? :create end \ No newline at end of file