Last active
October 6, 2016 17:53
-
-
Save froger/8c9b22ffbaff991d9f6c3430617ab47d to your computer and use it in GitHub Desktop.
Reflections methods on ActiveRecord relations, for serialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### | |
# Rails : 5.0.0 | |
# Ruby : 2.3.0 | |
# | |
# Reflections methods on ActiveRecord relations, for serialization | |
# purpose, for example. | |
# | |
# I used this to have some Hypermedia document when responding in JSON, | |
# with this informations, I could easily guess the _embedded links | |
# of my resources. | |
## | |
# Give an array of informations about each belongs_to associations | |
# of the ActiveRecord given. | |
# | |
# If the class given isn't an ActiveRecord, will return an empty array. | |
# | |
# | |
# Example of return | |
# ``` | |
# class Contact < ActiveRecord::Base | |
# belongs_to :user | |
# end | |
# | |
# | |
# > relation_infos(Contact, :belongs_to) | |
# [ | |
# { | |
# association_name: :user, | |
# association_klass_name: "User", | |
# association_klass: User, | |
# foreign_key: "user_id" | |
# } | |
# ] | |
# ``` | |
def relation_infos(model_klass, relation_type) | |
relations = [] | |
return relations unless | |
['has_one', | |
'belongs_to', | |
'has_many'].include?(relation_type.to_s.downcase) && | |
model_klass.respond_to?(:reflect_on_all_associations) | |
model_klass.reflect_on_all_associations(relation_type)\ | |
.collect do |association| | |
association_name = association.name | |
# Get the default association name, or the specified one in options hash. | |
if association.options.key?(:class_name) | |
klass_name = association.options[:class_name] | |
else | |
klass_name = association_name.to_s.singularize.camelize | |
end | |
klass = klass_name.to_s.constantize | |
# Get the default foreign key, or the specified one in options hash. | |
if association.options.key?(:foreign_key) | |
foreign_key = association.options[:foreign_key] | |
else | |
foreign_key = "#{klass.table_name.singularize}_id" | |
end | |
return { | |
association_name: association_name, | |
association_klass_name: klass_name, | |
association_klass: klass, | |
foreign_key: foreign_key | |
} | |
end | |
end | |
# Examples | |
# ======== | |
def belongs_to_infos(model_klass) | |
relation_infos(model_klass, :belongs_to) | |
end | |
def has_one_infos(model_klass) | |
relation_infos(model_klass, :has_one) | |
end | |
def has_many_infos(model_klass) | |
relation_infos(model_klass, :has_many) | |
end | |
puts 'Belongs to relations for User' | |
belongs_to_infos(User) | |
puts 'Has one relations for User' | |
has_one_infos(User) | |
puts 'Has many relations for User' | |
has_many_infos(User) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment