Skip to content

Instantly share code, notes, and snippets.

@alebian
Last active September 26, 2022 01:49
Show Gist options
  • Save alebian/b894edce00c1e5059c56c0512df53dac to your computer and use it in GitHub Desktop.
Save alebian/b894edce00c1e5059c56c0512df53dac to your computer and use it in GitHub Desktop.
module JsonSerializer
module_function
#
# Usage:
# JsonSerializer.find_by_id(User, 1, only: [:id, :email, :address], except: [:address])
#
def find_by_id(klass, id, options = {})
sql = "SELECT row_to_json(results) FROM (
SELECT #{selected_attributes(klass, options)}
FROM #{table_name(klass)}
WHERE id = #{id}
) as results"
find_by_sql(sql)
end
#
# Usage:
# JsonSerializer.find_all(User, only: [:id, email, :address], except: [:address])
#
def find_all(klass, options = {})
sql = "SELECT array_agg(row_to_json(results)) FROM (
SELECT #{selected_attributes(klass, options)}
FROM #{table_name(klass)}
) as results"
find_by_sql(sql)
end
def find_by_sql(sql)
result = ActiveRecord::Base.connection.execute(sql)
return '{}' if result.ntuples == 0
result.getvalue(0, 0)
end
def table_name(klass)
klass.table_name
end
def selected_attributes(klass, options)
only = options[:only].present? ? options[:only].map { |a| a.to_s } : []
exceptions = options[:except].present? ? options[:except].map { |a| a.to_s } : []
attributes = only.empty? ? klass.column_names : only
attributes = attributes.delete_if { |a| exceptions.include?(a) }
attributes.join(', ')
end
end
@kwerle
Copy link

kwerle commented Sep 20, 2017

table_name doesn't work for namespaced models. When I steal this code I'll replace it with klass.table_name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment