Module: BuddyTranslatable::Core

Defined in:
lib/buddy_translatable/core.rb

Instance Method Summary collapse

Instance Method Details

#define_translatable_finders(attr, is_json) ⇒ Object

Sample string value: "en":"key-1"



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/buddy_translatable/core.rb', line 83

def define_translatable_finders(attr, is_json) # rubocop:disable Metrics/MethodLength Metrics/AbcSize
  attr_query = sanitize_sql("#{table_name}.#{attr}")
  scope :"where_#{attr}_with", (lambda do |value|
    return where("#{attr_query} like ?", "%\":\"#{value}\"%") unless is_json

    where("EXISTS (SELECT 1 FROM jsonb_each_text(#{attr_query}) j WHERE j.value = ?)", value)
  end)

  scope :"where_#{attr}_like", (lambda do |value|
    return where("#{attr_query} like ?", "%#{value}%") unless is_json

    where("EXISTS (SELECT 1 FROM jsonb_each_text(#{attr_query}) j WHERE j.value LIKE ?)", "%#{value}%")
  end)

  scope :"where_#{attr}_eq", (lambda do |value, locale = I18n.locale|
    return where("#{attr_query} like ?", "%\"#{locale}\":\"#{value}\"%") unless is_json

    where("#{attr}->>'#{locale}' = ?", value)
  end)
end

#define_translatable_getters(attr) ⇒ Object

Sample:

model.title_data # ==> print values data
model.title # print value for current locale


56
57
58
59
60
61
62
63
64
# File 'lib/buddy_translatable/core.rb', line 56

def define_translatable_getters(attr)
  define_method("#{attr}_data") do
    BuddyTranslatable.parse_translatable_data(self[attr])
  end

  define_method(attr) do |**_args|
    send("#{attr}_data_for", I18n.locale)
  end
end

#define_translatable_key_getters(attr, fallback_locale) ⇒ Object

Sample:

model.title_for(:de) # ==> print value for provided locale
model.title_data_for(:de) # print value for provided locale


40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/buddy_translatable/core.rb', line 40

def define_translatable_key_getters(attr, fallback_locale)
  define_method("#{attr}_data_for") do |key|
    value = send("#{attr}_data")
    value[key].presence ||
      value[fallback_locale].presence ||
      value.values.find(&:present?)
  end

  define_method("#{attr}_for") do |key|
    send("#{attr}_data_for", key)
  end
end

#define_translatable_key_methods(attr, locales) ⇒ Object

Sample:

model.title_de # ==> "de title"
model.title_de = "new title" # assign value for specific locale


69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/buddy_translatable/core.rb', line 69

def define_translatable_key_methods(attr, locales)
  locales.each do |locale|
    define_method("#{attr}_#{locale}") do
      send("#{attr}_data_for", locale)
    end

    define_method("#{attr}_#{locale}=") do |value|
      data = send("#{attr}_data").merge(locale => value)
      send("#{attr}_data=", data)
    end
  end
end

#define_translatable_methods(attr, fallback_locale) ⇒ Object



13
14
15
16
17
18
19
# File 'lib/buddy_translatable/core.rb', line 13

def define_translatable_methods(attr, fallback_locale)
  is_json = BuddyTranslatable.translatable_attr_json?(self, attr)
  define_translatable_setters(attr, is_json)
  define_translatable_key_getters(attr, fallback_locale)
  define_translatable_getters(attr)
  define_translatable_finders(attr, is_json)
end

#define_translatable_setters(attr, is_json) ⇒ Object

Sample:

model.title_data = { de: 'de val', en: 'en val' } # ==> replace value data
model.title = { de: 'de val', en: 'en val' } # replace value data
model.title = 'custom value' # sets new value for current locale


25
26
27
28
29
30
31
32
33
34
35
# File 'lib/buddy_translatable/core.rb', line 25

def define_translatable_setters(attr, is_json)
  define_method("#{attr}_data=") do |arg|
    data = send("#{attr}_data")
    data = arg.is_a?(Hash) ? arg.symbolize_keys : data.merge(I18n.locale => arg)
    self[attr] = is_json ? data : data.to_json
  end

  define_method("#{attr}=") do |arg|
    send("#{attr}_data=", arg)
  end
end

#translatable(*attrs, default_key: I18n.default_locale, available_locales: nil) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/buddy_translatable/core.rb', line 5

def translatable(*attrs, default_key: I18n.default_locale, available_locales: nil)
  available_locales ||= I18n.available_locales
  attrs.each do |attr|
    define_translatable_methods(attr, default_key.to_sym)
    define_translatable_key_methods(attr, available_locales.map(&:to_sym))
  end
end