lib/jsonapionify/api/resource/definitions/attributes.rb in jsonapionify-0.9.0 vs lib/jsonapionify/api/resource/definitions/attributes.rb in jsonapionify-0.9.1

- old
+ new

@@ -7,45 +7,81 @@ extend JSONAPIonify::Types inherited_array_attribute :attributes delegate :id_attribute, :attributes, to: :class context(:fields, readonly: true) do |context| - should_error = false - fields = (context.request.params['fields'] || {}).each_with_object(self.class.api.fields) do |(type, fields), field_map| + should_error = false + input_fields = context.request.params['fields'] || {} + actionable_fields = self.class.fields_for_action(context.action_name, context) + input_fields.each_with_object( + actionable_fields + ) do |(type, fields), field_map| type_sym = type.to_sym + field_symbols = fields.to_s.split(',').map(&:to_sym) field_map[type_sym] = - fields.to_s.split(',').map(&:to_sym).each_with_object([]) do |field, field_list| - attribute = self.class.api.resource(type_sym).attributes.find do |attribute| - attribute.read? && attribute.name == field + field_symbols.each_with_object([]) do |field, field_list| + type_attributes = self.class.api.resource(type_sym).attributes + attribute = type_attributes.find do |attribute| + attribute.name == field && + attribute.supports_read_for_action?(context.action_name, context) end - attribute ? field_list << attribute.name : error(:field_not_permitted, type, field) && (should_error = true) + if attribute + field_list << attribute.name + else + error(:field_not_permitted, type, field) + should_error = true + end end + end.tap do + halt if should_error end - raise Errors::RequestError if should_error - fields end end end def id(sym) define_singleton_method :id_attribute do sym end end - def attribute(name, type, description = '', **options) - Attribute.new(name, type, description, **options).tap do |new_attribute| + def attribute(name, type, description = '', **options, &block) + Attribute.new( + name, type, description, **options, &block + ).tap do |new_attribute| attributes.delete(new_attribute) attributes << new_attribute end end + def remove_attribute(name) + attributes.delete_if { |attr| attr.name == name.to_sym } + end + def fields attributes.select(&:read?).map(&:name) end + def builder(&block) + context :builder, readonly: true, persisted: true do |context| + proc do |resource, instance| + block.call resource, instance, context + end + end + end + def field_valid?(name) fields.include? name.to_sym + end + + def fields_for_action(action, context) + api.fields.each_with_object({}) do |(type, attrs), fields| + fields[type] = attrs.select do |attr| + api.resource(type).attributes.find do |type_attr| + type_attr.name == attr + end.supports_read_for_action? action, context + end + end end end end