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