rails_db_localize 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +44 -7
- data/app/models/rails_db_localize/translation.rb +9 -2
- data/lib/ext/active_record_ext.rb +37 -0
- data/lib/rails_db_localize/translation_cache.rb +1 -1
- data/lib/rails_db_localize/version.rb +1 -1
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +3970 -0
- metadata +1 -3
- data/test/dummy/tmp/pids/server.pid +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6dddf4c074ccd2e53d6ae27b8f6894b3036760a8
|
4
|
+
data.tar.gz: 5093a12848cb94da0b88ffba1996f83de8bcfc82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a1b65ecb96440a0135817ed14dcb1a2560da07422d084007af852ba617ee994559586b0a5b01c05ee7d566ba8dd9d21386d29590b295f121425bdfc441dabd8
|
7
|
+
data.tar.gz: fe7630b9035ac83ee4565bbcc71e12e00d14084e9cac2d121d707290a6b7b7fecbcaf56e30b6e62f6d72f9d5709fa175df315fda6c73a9aba6ca553bb3d9820a
|
data/README.md
CHANGED
@@ -9,21 +9,20 @@ The most annoying part is globalize3 create a table for each object you want to
|
|
9
9
|
|
10
10
|
I've made this gem with theses rules in head:
|
11
11
|
|
12
|
-
|
12
|
+
### 1/ Translation just in time.
|
13
13
|
|
14
14
|
You don't need to think about translation in your project until you begin the translation process.
|
15
15
|
`rails_db_localize` doesn't modify your database schematic but instead just add a layer on it.
|
16
16
|
|
17
|
-
|
17
|
+
### 2/ One table to bring them all.
|
18
18
|
|
19
19
|
`rails_db_localize` add only one table to your project. All your translations are stored inside this table.
|
20
20
|
This allow you to make without any pain a tool to manage a team of traductors for example.
|
21
21
|
|
22
22
|
Since everything is in the same table, one controller is enough to manage the translation process!
|
23
|
-
About performance, `rails_db_localize` use some
|
23
|
+
About performance, `rails_db_localize` use some optimizations for fetching the rows (caching and hashing system).
|
24
24
|
|
25
|
-
|
26
|
-
## 3/ Only one query for all your translations
|
25
|
+
### 3/ Only one query for all your translations
|
27
26
|
|
28
27
|
Thanks to the caching system, `rails_db_localize` need only one query to retrieve all the translations of your current view (see below)
|
29
28
|
|
@@ -77,7 +76,7 @@ or:
|
|
77
76
|
model.name_translated = "Name in french", :fr
|
78
77
|
```
|
79
78
|
|
80
|
-
# SQL
|
79
|
+
# SQL Optimization
|
81
80
|
|
82
81
|
To avoid N+1 requests, please use the preloader on every array of models you want to use:
|
83
82
|
|
@@ -86,11 +85,49 @@ To avoid N+1 requests, please use the preloader on every array of models you wan
|
|
86
85
|
@categories = Category.all
|
87
86
|
#Only one request per preload_translations_for call
|
88
87
|
preload_translations_for(@translatables, @categories)
|
88
|
+
|
89
|
+
#If you have only one set of data, you can use the model method:
|
90
|
+
@categories.preload_translations
|
89
91
|
```
|
90
92
|
|
93
|
+
# Other features
|
94
|
+
|
95
|
+
Each model having at least a translated field can use `missing_translation` and `having_translation`
|
96
|
+
|
97
|
+
Theses methods allow you to filters your models if they are translated or not.
|
98
|
+
|
99
|
+
### Blog case:
|
100
|
+
|
101
|
+
You have a blog with articles in two languages but you don't translate all articles.
|
102
|
+
To show articles from the current langage selected on your blog, you can use:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
def index
|
106
|
+
@articles = Articles.having_translation(I18n.locale).all
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
### Other case:
|
111
|
+
|
112
|
+
You have a team of translators:
|
113
|
+
- One can translate from english to french
|
114
|
+
- Another one can translate from french to spanish
|
115
|
+
|
116
|
+
You just have to filters the articles in your translation tool like this:
|
117
|
+
```ruby
|
118
|
+
Articles.having_translation(translator.from_language).missing_translation(translator.to_language)
|
119
|
+
```
|
120
|
+
Create two users with role translator with from/to_language "en/fr" and "fr/es". Et voilà!
|
121
|
+
|
91
122
|
# Changelog
|
92
123
|
|
93
|
-
0.
|
124
|
+
## 0.2
|
125
|
+
|
126
|
+
Add methods `having_translation`, `missing_translation` and `preload_translation`
|
127
|
+
|
128
|
+
## 0.1
|
129
|
+
|
130
|
+
First commit
|
94
131
|
|
95
132
|
# Licensing
|
96
133
|
|
@@ -15,11 +15,18 @@ class RailsDbLocalize::Translation < ActiveRecord::Base
|
|
15
15
|
|
16
16
|
before_validation :set_compound_key
|
17
17
|
|
18
|
+
|
19
|
+
|
18
20
|
def self.generate_ck resource_type, resource_id
|
19
|
-
|
20
|
-
|
21
|
+
hash_long = [resource_type.to_s.underscore, resource_id].join("|").chars.map(&:ord).inject(5381) do |h, v|
|
22
|
+
h = ((h<<5)+h)+v
|
23
|
+
end
|
24
|
+
|
25
|
+
#Keep it signed 32bits.
|
26
|
+
hash_long & 0x7fffffff
|
21
27
|
end
|
22
28
|
|
29
|
+
|
23
30
|
def self.get_untranslated model, field, lang
|
24
31
|
model.where("id NOT IN (?)",
|
25
32
|
[-1, *RailsDbLocalize::Translation.where(resource_type: k.to_s, lang: lang, field: field).pluck(:resource_id).uniq]
|
@@ -7,6 +7,38 @@ class ActiveRecord::Base
|
|
7
7
|
@__rdbl_translations = true
|
8
8
|
# Register it mostly to remove the translations once you delete an object
|
9
9
|
self.has_many :translations, as: :resource, dependent: :destroy
|
10
|
+
|
11
|
+
scope :__rails_db_translations_sub_query, lambda{ |lang|
|
12
|
+
ttable = RailsDbLocalize::Translation.arel_table.name
|
13
|
+
number_of_fields_to_translates = RailsDbLocalize.schema[self.to_s].count
|
14
|
+
|
15
|
+
# We can unscope, but problems tend to appears
|
16
|
+
# with some gems like paranoid.
|
17
|
+
table = respond_to?(:klass) ? table.klass : self
|
18
|
+
|
19
|
+
table.select(:id).joins("INNER JOIN \"#{ttable}\"
|
20
|
+
ON (\"#{ttable}\".resource_id = \"#{arel_table.name}\".id
|
21
|
+
AND \"#{ttable}\".resource_type = '#{to_s}')")
|
22
|
+
.group(:resource_type, :resource_id)
|
23
|
+
.having("COUNT(*) == #{number_of_fields_to_translates}")
|
24
|
+
.where(:"rails_db_localize_translations.lang" => lang)
|
25
|
+
}
|
26
|
+
|
27
|
+
# Return all rows with missing translation for a selected language.
|
28
|
+
self.scope :missing_translation, lambda{ |lang|
|
29
|
+
where("\"#{arel_table.name}\".id NOT IN (#{__rails_db_translations_sub_query(lang).to_sql})")
|
30
|
+
}
|
31
|
+
|
32
|
+
# Return all rows with translation OK for a selected language.
|
33
|
+
self.scope :having_translation, lambda{ |lang|
|
34
|
+
where("\"#{arel_table.name}\".id IN (#{__rails_db_translations_sub_query(lang).to_sql})")
|
35
|
+
}
|
36
|
+
|
37
|
+
def self.preload_translations
|
38
|
+
RailsDbLocalize::TranslationCache.instance.prefetch_collections(self)
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
10
42
|
end
|
11
43
|
|
12
44
|
fields.each do |field|
|
@@ -20,6 +52,11 @@ class ActiveRecord::Base
|
|
20
52
|
# I should really learn how to use the Reflection helpers in ActiveRecord, because
|
21
53
|
# ruby eval is not the most readable stuff... :o)
|
22
54
|
self.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
55
|
+
def #{field}_translated_exists?(lang=nil)
|
56
|
+
lang ||= I18n.locale
|
57
|
+
!!RailsDbLocalize::TranslationCache.instance.get_translation_for(self.class, self.id, "#{field}", lang, nil )
|
58
|
+
end
|
59
|
+
|
23
60
|
def #{field}_translated (lang=nil)
|
24
61
|
lang ||= I18n.locale
|
25
62
|
RailsDbLocalize::TranslationCache.instance.get_translation_for(self.class, self.id, "#{field}", lang, self.#{field} )
|
@@ -60,7 +60,7 @@ public
|
|
60
60
|
encache RailsDbLocalize::Translation.where("compound_key IN (?)", in_clause).pluck(:resource_type, :resource_id, :field, :lang, :content)
|
61
61
|
end
|
62
62
|
|
63
|
-
def get_translation_for model_class, model_id, field, lang, default
|
63
|
+
def get_translation_for model_class, model_id, field, lang, default=nil
|
64
64
|
ck = RailsDbLocalize::Translation.generate_ck(model_class, model_id)
|
65
65
|
|
66
66
|
if @cache[:cks][ck]
|
Binary file
|