Class: Pluckers::Base

Overview

This is the base class for all pluckers.

It receives all the configuration in the ‘initialize` method and performs all the sql queries and hash building inside the `pluck` method.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Features::Pluck

#all_method, #pluck_records

Methods included from Features::Base::Pluck

#all_method, #pluck_records

Methods included from Features::BelongsToReflections

#active_record_belongs_to_reflection?

Methods included from Features::BelongsToPolymorphicReflections

#active_record_belongs_to_polymorphic_reflection?

Methods included from Features::HasManyReflections

#active_record_has_many_reflection?

Methods included from Features::HasManyThroughReflections

#active_record_has_many_through_reflection?

Methods included from Features::HasAndBelongsToManyReflections

#active_record_has_and_belongs_to_many_reflection?, #has_and_belongs_to_many_ids

Methods included from Features::HasOneReflections

#active_record_has_one_reflection?

Methods included from Features::HasOneThroughReflections

#active_record_has_one_through_reflection?

Constructor Details

#initialize(records, options = {}) ⇒ Base

In the initialize method we recive all the options for the plucker.

First, we receive an ActiveRecord Relation. It can be any ActiveRecord scope such as ‘BlogPost.all` or `BlogPost.published`. If we want to pluck a particular object we could pass `BlogPost.where(id: post.id )` so we have an ActiveRecord relation.

The options hash allows us to send a lot of configuration that will be used by all the features and subclasses to decorate the very basic behaviour.

Currently, the options supported by the features included in this base plucker are:

* attributes: Names of attributes of the objects to be plucked. This
  attributes should be the names of the columns in the database. If we are
  using Globalize these attributes can also be  the names of the translated
  attributes by Globalize.

* attributes_with_locale: A hash when the key is a locale and the value
  is an array of attributes to pluck. As a result we will have a series of
  attributes with the name following the syntax attreibute_locale. E.g: The
  option could be { es: [:name], en: [:name, :location]} and we would obtain
  :name_es, :name_en and :location_en keys in the hash result

* renames: A hash of the attributes/reflections/whatever that will be
  renamed. The key is the old name and the value is the new name.

* 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 options.

  - 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.

  - only_ids: In has_many reflections we can get the _ids array instead
    of an array with hashes if we pass this option as true. If we do any
    fields or plucker option will be ignored.

  - Any other option will be passed to the plucker, so you can send any
    other regular option such as fields, custom ones or even more
    reflections. Recursivity FTW!!

The options hash can be used by subclasses to decorate all this behaviour and send params inside the plucker.



83
84
85
86
87
# File 'lib/pluckers/base.rb', line 83

def initialize records, options = {}
  @records = records
  @options = options
  @features = @options.delete(:features)
end

Instance Attribute Details

#recordsObject (readonly)

In this attribute we store the ActiveRecord Relation we use to fetch information from the database



31
32
33
# File 'lib/pluckers/base.rb', line 31

def records
  @records
end

Instance Method Details

#build_resultsObject

In this base implementation we perform the real pluck execution.

The method collects all the attributes and columns to pluck and add it to the results array.



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
# File 'lib/pluckers/base.rb', line 126

def build_results

  # Now we uinq the attributes
  @attributes_to_pluck.uniq!{|f| f[:name] }

  # Obtain both the names and SQL columns
  names_to_pluck = @attributes_to_pluck.map{|f| f[:name] }
  sql_to_pluck = @attributes_to_pluck.map{|f| f[:sql] }


  # And perform the real ActiveRecord pluck.
  pluck_records(sql_to_pluck).each_with_index do |record, index|
    # After the pluck we have to create the hash for each record.

    # If there's only a field we will not receive an array. But we need it
    # so we built it.
    record = [record] unless record.is_a? Array
    # Now we zip it with the attribute names and create a hash. If we have
    # have a record: [1, "Test title 1", "Test text 1"] and the
    # names_to_pluck are [:id, :title, :text] we will end with {:id=>1,
    # :title=>"Test title 1", :text=>"Test text 1"}
    attributes_to_return = Hash[names_to_pluck.zip(record)]

    # Now we store it in the results hash
    @results[attributes_to_return[:id]] = attributes_to_return
  end
end

#configure_queryObject

In this base implementation we just reset all the query information. Features and subclasses must redefine this method if they are interested in adding some behaviour.



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/pluckers/base.rb', line 107

def configure_query
  @query_to_pluck = @records
  @attributes_to_pluck = [{ name: @query_to_pluck.primary_key.to_sym, sql: "\"#{@query_to_pluck.table_name}\".#{@query_to_pluck.primary_key}" }]
  @results = {}
  @klass_reflections = @query_to_pluck.reflections.with_indifferent_access

  pluck_reflections = @options[:reflections] || {}

  # Validate that all relations exists in the model
  if (missing_reflections = pluck_reflections.symbolize_keys.keys - @klass_reflections.symbolize_keys.keys).any?
    raise ArgumentError.new("Plucker reflections '#{missing_reflections.to_sentence}', are missing in #{@records.klass}")
  end
end

#pluckObject

This method performs all the sql and hash building according to the received configuration.



92
93
94
95
96
97
98
99
100
101
# File 'lib/pluckers/base.rb', line 92

def pluck
  return [] if @records.blank?

  configure_query

  build_results

  # And return the results
  @results.values
end