Module: Pluckers::Features::Base::BelongsToPolymorphicReflections
- Included in:
- Pluckers::Features::BelongsToPolymorphicReflections
- Defined in:
- lib/pluckers/features/base/belongs_to_polymorphic_reflections.rb
Overview
This module implements plucking belongs_to polymorphic relationships in a recursive way.
The options used in this feature are:
* reflections: A hash of the reflections we will pluck recursively. The
key of this hash will be the name of the reflection and the value is
another hash of .
In the case of a polymorphic relationship, this will be a hash
where you will set the plucking for each different
available model. Keys of the hash wil be names of the models and
the values will be the regular for a standard reflection:
- scope: You can limit the scope of the objects plucked. E.g, you
could use Author.active instead of Author.all. Notice that .all is
the default.
- plucker: You can use a custom plucker instead of Pluckers::Base in
case you want any specific logic. Pluckers::Base is the default
one.
- Any other option will be passed to the plucker, so you can send any
other regular option such as attributes, custom ones or even more
reflections. Recursivity FTW!! (even in polymorphic relations)
Instance Method Summary collapse
-
#build_results ⇒ Object
In this method we get the reflections and for each one creates and executes a new plucker.
-
#configure_query ⇒ Object
Here we obtain the belongs_to reflections to include in the pluck operation and also include the relation foreign key in the attributes to pluck for this model.
Instance Method Details
#build_results ⇒ Object
In this method we get the reflections and for each one creates and executes a new plucker.
This pluck gives the whole process a recursive character and options for that plucker may be passed in the options hash.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/pluckers/features/base/belongs_to_polymorphic_reflections.rb', line 92 def build_results super return if @belongs_to_polymorphic_reflections.blank? # For each reflection @belongs_to_polymorphic_reflections.each do |name, reflection| # As an example we will imagine that we are plucking BlogPosts and # this relation is the Subject # First, we get the meta information about the reflection klass_reflection = @klass_reflections[name] reflection_primary_key = klass_reflection.active_record_primary_key.to_sym reflection_foreign_key = klass_reflection.foreign_key.to_sym reflection_foreign_type = klass_reflection.foreign_type.to_sym # Now, we group all the already plucked _type and _id attributes, so # we can pluck the polymorphic models polymporphic_models = {} @results.each do |_, r| next if r[reflection_foreign_type].nil? || r[reflection_foreign_key].nil? polymporphic_models[r[reflection_foreign_type]] ||= [] polymporphic_models[r[reflection_foreign_type]] << r[reflection_foreign_key] end # Now we have a hash like { # "Category" => [1, 2, 3], "Author" => [4, 2, 8] # } # We initialize so we return a nil if there are no record related @results.each do |_,result| result[name] = nil end polymporphic_models.each do |model_name, model_ids| = reflection[model_name.to_sym] # If there are no options for a model we don't pluck them next if .nil? # initialize some options such as the plucker or the scope of the pluck scope = [:scope] || model_name.constantize.send(all_method) plucker = [:plucker] || Pluckers::Base # And now we create the plucker. Notice that we add a where to the # scope, so we filter the records to pluck as we only get those with # an id in the set of the foreign keys of the records already # plucked by the base plucker # # In our Example we would be doing something like # Author.all.where(id: author_ids) reflection_plucker = plucker.new scope.where( reflection_primary_key => model_ids ), # And now pluck the related class and process the results reflection_plucker.pluck.each do |r| # For each related result (Author or Category) we search those # records (BlogPost) that are related (post.subject_id == # author.id o post.subject_id == category.id) and insert them in # the relationship attributes @results.each do |_,result| if result[reflection_foreign_key] == r[reflection_primary_key] && result[reflection_foreign_type] == model_name result[name] = r end end end end end end |
#configure_query ⇒ Object
Here we obtain the belongs_to reflections to include in the pluck operation and also include the relation foreign key in the attributes to pluck for this model.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/pluckers/features/base/belongs_to_polymorphic_reflections.rb', line 47 def configure_query super pluck_reflections = [:reflections] || {} return if pluck_reflections.blank? @belongs_to_polymorphic_reflections = { } # We iterate through the class reflections passed as options @klass_reflections.slice(*pluck_reflections.keys). # And select those that are BelongsTo select{|_, r| active_record_belongs_to_polymorphic_reflection?(r) }. # And store them in the belongs_to_reflection hash that will be used later each do |name, reflection| name = name.to_sym @belongs_to_polymorphic_reflections[name] = pluck_reflections[name] end # First thing we do is to include the foreign key in the attributes to # pluck array, so the base plucker plucks them @belongs_to_polymorphic_reflections.each do |name, _| foreign_key_name = @klass_reflections[name].foreign_key @attributes_to_pluck << { name: foreign_key_name.to_sym, sql: foreign_key_name } foreign_type = @klass_reflections[name].foreign_type @attributes_to_pluck << { name: foreign_type.to_sym, sql: foreign_type } end end |