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
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
|
# File 'lib/localizable_db/localizable.rb', line 20
def localize(*localizable_attributes)
self.is_localizable = true
class_eval do
default_scope(if: LocalizableDb.configuration.enable_i18n_integration) do
localized
end
mattr_accessor :localized_table_name
mattr_accessor :normalized_table_name
mattr_accessor :localizable_attributes
end
self.localized_table_name = "#{self.table_name.singularize}_languages"
self.normalized_table_name = self.table_name
self.localizable_attributes = localizable_attributes
aux_localized_table_name = self.localized_table_name
aux_model_name = self.name
self.const_set("#{self.name}Language", Class.new(ApplicationRecord) do
self.table_name = aux_localized_table_name
belongs_to aux_model_name.downcase.to_sym,
class_name: aux_model_name,
foreign_key: "localizable_object_id",
inverse_of: aux_localized_table_name.to_sym
end)
class_eval do
has_many self.localized_table_name.to_sym,
class_name: "#{self.name}Language",
foreign_key: "localizable_object_id",
inverse_of: aux_model_name.downcase.to_sym,
dependent: :destroy
accepts_nested_attributes_for self.localized_table_name.to_sym
end
if LocalizableDb.configuration.enable_getters
self.localizable_attributes.each do |attribute|
class_eval %Q{
def get_#{attribute}(language = LocalizableDb::Languages::DEFAULT)
if language == LocalizableDb::Languages::DEFAULT
self.attributes["#{attribute.to_s}"]
else
self.attributes[language.to_s + "_#{attribute.to_s}"]
end
end
}
end
end
class << self
def get_locale
I18n.locale
end
def localized(*languages)
if(defined? LocalizableDb::Localizable and
((LocalizableDb.configuration.enable_i18n_integration and self.get_locale != LocalizableDb::Languages::DEFAULT) or
(languages.any? and (languages-[LocalizableDb::Languages::DEFAULT]).any?)))
languages = LocalizableDb::Languages::SUPPORTED if(
languages.any? and languages.first == :all)
languages = [self.get_locale] if languages.empty? and LocalizableDb.configuration.enable_i18n_integration
languages.map!{|language| language.to_sym}
if languages.size == 1
language = languages.first
return one_language(language)
else
languages = languages.keep_if do |language|
LocalizableDb::Languages::NOT_DEFAULT.include? language
end
return multiple_languages(languages)
end
else
ActiveRecord::Relation.new(self, self.table_name,self.predicate_builder)
end
end
alias_method :l, :localized
private
def one_language(language)
attrs_to_select = single_languege_attrs_to_select_conf(language)
from("#{self.localized_table_name}").joins("
JOIN (
SELECT #{self.table_name}.id, #{attrs_to_select.join(',')}
FROM #{self.localized_table_name}, #{self.table_name}
WHERE #{self.localized_table_name}.locale = '#{language.to_s}'
AND #{self.localized_table_name}.localizable_object_id = #{self.table_name}.id
) AS #{self.table_name}
ON #{self.localized_table_name}.locale = '#{language.to_s}'
AND #{self.localized_table_name}.localizable_object_id = #{self.table_name}.id
")
end
def multiple_languages(languages)
attrs_to_select = (self.attribute_names).map do |attribute|
"#{self.table_name}.#{attribute.to_s}"
end
tables_to_select = ""
conditions_to_select = ""
languages.each do |language|
attrs_to_select = attrs_to_select | self.localizable_attributes.map do |attribute|
"#{language.to_s}_#{self.localized_table_name}.#{attribute.to_s} as #{language.to_s}_#{attribute.to_s}"
end
tables_to_select += "," if language != languages.first
tables_to_select += "#{self.localized_table_name} as #{language.to_s}_#{self.localized_table_name}"
conditions_to_select += "#{language.to_s}_#{self.localized_table_name}.locale = '#{language.to_s}'"
conditions_to_select += " AND #{language.to_s}_#{self.localized_table_name}.localizable_object_id = #{self.table_name}.id"
conditions_to_select += " AND " if language != languages.last
end
from("#{tables_to_select}").joins("
JOIN (
SELECT #{self.table_name}.id, #{attrs_to_select.join(',')}
FROM #{self.table_name}, #{tables_to_select}
WHERE #{conditions_to_select}
) AS #{self.table_name}
ON #{conditions_to_select}
")
end
def single_languege_attrs_to_select_conf(language = nil)
if LocalizableDb.configuration.attributes_integration
attrs_to_select = self.attribute_names - ["id"] - self.localizable_attributes.map do |attribute|
attribute.to_s
end
attrs_to_select = attrs_to_select | self.localizable_attributes.map do |attribute|
["#{self.localized_table_name}.#{attribute.to_s}","#{self.localized_table_name}.#{attribute.to_s} as #{language}_#{attribute}"]
end
attrs_to_select.flatten!
else
attrs_to_select = self.attribute_names - ["id"]
attrs_to_select = attrs_to_select.map do |attribute|
"#{self.table_name}.#{attribute}"
end | self.localizable_attributes.map do |attribute|
"#{self.localized_table_name}.#{attribute.to_s} as #{language}_#{attribute}"
end
end
attrs_to_select
end
end
end
|