Module: Pluckers::Features::Base::Globalize

Included in:
Globalize
Defined in:
lib/pluckers/features/base/globalize.rb

Overview

This module implements plucking belongs_to relationships in a recursive way.

The options used in this feature are:

* attributes: Names of attributes of the objects to be plucked. This
  attributes should 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

Instance Method Summary collapse

Instance Method Details

#configure_queryObject

Here we include in the @attributes_to_pluck array the attribute names and SQL required for Globalize



34
35
36
37
38
39
40
41
42
43
44
45
46
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/pluckers/features/base/globalize.rb', line 34

def configure_query
  super

  return if @klass_reflections[:translations].nil?

  if @options[:attributes]

    # First we get those attributes received bia the attributes option
    # that must be translated
    plucker_attributes = @options[:attributes].map(&:to_sym)

    klass_translated_attributes = @records.try(:translated_attribute_names) || []
    klass_translated_attributes = klass_translated_attributes.map(&:to_sym)

    @translated_attributes = plucker_attributes & klass_translated_attributes

    # And we remove it from the attributes options, so the simple
    # attributes feature don't receive them
    @options[:attributes] = plucker_attributes - klass_translated_attributes

  end

  # And initialize with an empty array if we didn't receive any
  @translated_attributes ||= []

  # And then get the attributes that must be returned for a specific locale
  @attributes_with_locale = @options[:attributes_with_locale] || {}

  unless @translated_attributes.blank? && @attributes_with_locale.blank?

    # We obtain the info about the translations relation
    translation_table_name = @records.klass::Translation.table_name
    translation_foreign_key = @klass_reflections[:translations].foreign_key

    # And we perform a join for each locale
    fallbacks = ::Globalize.fallbacks(::Globalize.locale)

    fallbacks.each do |locale|
      @records = @records.joins(
        "LEFT OUTER JOIN #{@records.klass.connection.quote_table_name translation_table_name} AS locale_#{locale}_translation ON (
          #{@records.klass.connection.quote_table_name @records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
          locale_#{locale}_translation.locale = '#{locale}'
        )")

    end

    # The attribute to pluck must get the first non nil field
    @attributes_to_pluck += @translated_attributes.map do |field|
      {
        name: field,
        sql: "COALESCE(NULL, #{
          fallbacks.map{|locale| "locale_#{locale}_translation.#{field}" }.join(',')
          })"
      }
    end

    # For the attributes with locale (name_es, name_en...)
    @attributes_with_locale.each do |locale, attributes|

      # We add the locales that are not fallback
      unless fallbacks.include? locale
        @records = @records.joins(
          "LEFT OUTER JOIN #{@records.klass.connection.quote_table_name translation_table_name} AS locale_#{locale}_translation ON (
            #{@records.klass.connection.quote_table_name @records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
            locale_#{locale}_translation.locale = '#{locale}'
          )")
      end

      # And we add the attribute to be plucked
      @attributes_to_pluck += attributes.map do |field|
        {
          name: "#{field}_#{locale}".to_sym,
          sql: "locale_#{locale}_translation.#{field}"
        }
      end
    end
  end
end