Module: AttributeLocalizer::ClassMethods

Defined in:
lib/attribute_localizer.rb

Instance Method Summary collapse

Instance Method Details

#localize_attributes(*attributes) ⇒ Object Also known as: localize_attribute



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
112
113
# File 'lib/attribute_localizer.rb', line 9

def localize_attributes(*attributes)
  options = attributes.extract_options!

  klass = class << self; self end

  class_eval 'after_save :serialize_localizations'
  class_eval 'attr_accessor :locale' if options[:locale_virtual]
  attributes.each { |attribute| class_eval "attr_accessor :#{attribute}" }

  src = attributes.map do |attribute|
    str = "def #{attribute}\n"
    str << "  return @#{attribute} if @#{attribute}\n"
    str << "  @#{attribute} = I18n.t(\"\#{self.class.send :localization_namespace}.\#{localization_hash_key}.#{attribute}\", :locale => locale, :default => '')\n"
    str << "  @#{attribute} = nil unless @#{attribute}.present?\n"
    str << "  @#{attribute}\n"
    str << "end\n"
    str
  end.join("\n")

  module_eval src, __FILE__, __LINE__

  src = <<-end_src

    def locale
      #{options[:locale_virtual] ? '@locale' : 'super'} || I18n.locale
    end

  end_src

  module_eval src, __FILE__, __LINE__


  private

    klass.send :define_method, 'i18n_file' do |locale|
      "#{RAILS_ROOT}/config/locales/#{localization_namespace}/#{locale}.yml"
    end

    klass.send :private, 'i18n_file'

    src = <<-end_src

      def load_locale_data(locale)
        localized_hash = YAML::load_file(i18n_file(locale))
        localized_hash[locale][localization_namespace]
      rescue
        {}
      end

      def instantiate(record)
        object = super
        object.instance_variable_get('@attributes').merge!(#{attributes.map { |attribute| "'#{attribute}' => nil" }.join(', ') })
        object
      end

    end_src

    klass.class_eval src, __FILE__, __LINE__

    klass.send :private, 'load_locale_data'
    klass.send :private, 'instantiate'

    klass.send :define_method, 'localization_namespace' do
      to_s.underscore.pluralize
    end

    klass.send :private, 'localization_namespace'

    klass.send :define_method, 'write_locale_data' do |locale, localized_hash|
      File.open( i18n_file(locale), File::WRONLY|File::TRUNC|File::CREAT ) do |out|
        YAML.dump( { locale => {localization_namespace => localized_hash} }, out )
      end
    end

    klass.send :private, 'write_locale_data'

    src = <<-end_src

      private

        def attributes_from_column_definition
          super.merge(#{attributes.map { |attribute| "'#{attribute}' => nil" }.join(', ') })
        end

        def localization_hash_key
          "_\#{id}".to_sym
        end

        def localized_yaml
          {
          #{attributes.map { |attribute| ":#{attribute} => #{attribute}"}.join(',')}
          }
        end

        def serialize_localizations
          localized_hash = self.class.send :load_locale_data, locale
          localized_hash[localization_hash_key] = localized_yaml
          self.class.send :write_locale_data, locale, localized_hash
        end

    end_src

    module_eval src, __FILE__, __LINE__

end