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