api: refactor api attribute declarations.

Replace the `method_attributes` and `hidden_attributes` methods with
`api_attributes`. `api_attributes` can be used as a class macro:

    # include only the given attributes.
    api_attributes :id, :created_at, :creator_name, ...

    # include all default attributes plus the `creator_name` method.
    api_attributes including: [:creator_name]

or as an instance method:

    def api_attributes
       [:id, :created_at, :creator_name, ...]
    end

By default, all attributes are included except for IP addresses and
tsvector columns.
This commit is contained in:
evazion
2019-09-08 23:28:02 -05:00
parent 19f2cc1e74
commit d0f060d8eb
22 changed files with 98 additions and 209 deletions

View File

@@ -215,35 +215,47 @@ class ApplicationRecord < ActiveRecord::Base
module ApiMethods
extend ActiveSupport::Concern
def serializable_hash(options = {})
options ||= {}
class_methods do
def api_attributes(*attributes, including: [])
return @api_attributes if @api_attributes
options[:include] ||= []
if attributes.present?
@api_attributes = attributes
else
@api_attributes = attribute_types.reject { |name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
end
options[:except] ||= []
options[:except] += hidden_attributes
options[:methods] ||= []
options[:methods] += method_attributes
if options[:only]
options[:methods] = options[:methods] & options[:only].map(&:to_sym)
options[:include] = options[:include] & options[:only].map(&:to_sym)
@api_attributes += including
@api_attributes
end
end
def api_attributes
self.class.api_attributes
end
def serializable_hash(options = {})
options[:only] ||= []
options[:include] ||= []
options[:methods] ||= []
attributes, methods = api_attributes.partition { |attr| has_attribute?(attr) }
methods += options[:methods]
includes = options[:include]
if options[:only].present?
attributes &= options[:only]
methods &= options[:only]
includes &= options[:only]
end
options[:only] = attributes
options[:methods] = methods
options[:include] = includes
hash = super(options)
hash.transform_keys { |key| key.delete("?") }
end
protected
def hidden_attributes
[:uploader_ip_addr, :updater_ip_addr, :creator_ip_addr]
end
def method_attributes
[]
end
end
concerning :ActiveRecordExtensions do