from_clause_translate 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61a7a0b83c04d5cc4e15a088c9a56ad2388700bc1a6de3c477860501fdcfd16e
4
- data.tar.gz: 1fd848f0dda4626997dc32742616117b4fcc3017219a30133d3c585ec0408a2a
3
+ metadata.gz: e2a0a04072d1c8cb05f90443fa05aa74ffceaced4a714761abe83940b36a694a
4
+ data.tar.gz: 9c01576a7a7dcb5124bf82a0b8d88c61d67126bcbf41dc9dabec1d3c2878f2c4
5
5
  SHA512:
6
- metadata.gz: 85e5ab0a94cd12927ed91ac819d4c4775374dbb217cf23d4511d9c4f292ba11ff5470c1d444b01fff500c51c737dc52904ff0a60f3dac75cdb695dfab8779c45
7
- data.tar.gz: 4e032681587d35263fbae5bdf3f70b06f51f10104c3495ffa311d0fef8ec195759825d2b36a239c4a04a609fa19966376a9a14fbfe9f7fe4d0b479a642bb7b3a
6
+ metadata.gz: 4ad0b659cd25294a584f9bf293f74fbda4006b1f71bea76ba0cdd0abc293a6177dd027dc204a13173d8a4ca361b34c665f392e49fa59617828142f6731c6114c
7
+ data.tar.gz: 8437b273f89e0780289287f26cef363a56ffab850c2133226a49a73ca2c45597f38aaf8e982cbb175988d6f4872b9f8291e0d4442d4c0c3cb00203770a46ad81
data/README.md CHANGED
@@ -1,8 +1,155 @@
1
1
  # FromClauseTranslate
2
- Short description and motivation.
2
+ This gem extends ActiveRecord models for easy manipulations with multilanguage data.
3
+
4
+ The name of gem stands for way that it is doing its magic - SQL's `FROM` statement.
5
+
6
+ The main idea is that you can have database columns `name_en`, `name_ru`, `name_fr` and you will still able to filter data with `WHERE name LIKE '%some name%'`, all `SQL` statements will be working with just `name` column.
7
+
8
+ It allows making of complex `SQL` queries without need of interpolation of `I18n.locale` and without joining separate translation tables.
9
+
10
+ ## Requirements
11
+
12
+ Activerecord.
13
+
14
+ Postgresql, other databases were not tested.
3
15
 
4
16
  ## Usage
5
- How to use my plugin.
17
+ Lets have translatable model `Post`:
18
+
19
+ ```ruby
20
+ class CreatePosts < ActiveRecord::Migration[5.2]
21
+ def change
22
+ create_table :posts do |t|
23
+ %i[en ru uk de fr it es].each do |locale|
24
+ t.string "slug_#{locale}"
25
+ t.string "name_#{locale}"
26
+ t.string "title_#{locale}"
27
+ t.string "text_#{locale}"
28
+ t.boolean "translated_#{locale}", null: false, default: false
29
+ end
30
+ end
31
+ end
32
+ end
33
+ ```
34
+
35
+ In migration array of locales should be hardcoded, because when new language will be added in future, this migration will still be reversable.
36
+
37
+ Then this `FromClauseTranslate` should be included in `AplicationRecord` or in the required model:
38
+
39
+ ```ruby
40
+ class ApplicationRecord < ActiveRecord::Base
41
+ include FromClauseTranslate
42
+
43
+ self.abstract_class = true
44
+ end
45
+ ```
46
+
47
+ Make columns in the model translatable:
48
+
49
+ ```ruby
50
+ class Post < ApplicationRecord
51
+ translates :name, :title, :text, :slug, :translated, plurals: %i[slugs translateds]
52
+ end
53
+ ```
54
+
55
+ About plurals will be down below, now this model supports getting and setting values:
56
+
57
+ ```ruby
58
+ post = Post.new(name: 'Name for current locale')
59
+ post.name == 'Name for current locale' # true
60
+ post.name = 'New name'
61
+ post.name_fr = 'French name of post' # real columns are still accessible
62
+ ```
63
+
64
+ Such ActiveRecord column methods are supported (star for column name):
65
+ `save_change_to_*`, `*_changed?`, `*_before_last_save`, `*_change_to_be_saved`, `*_in_database`, `saved_change_to_*?`, `will_save_change_to_*?`
66
+
67
+ ## Querying
68
+
69
+ Following code will get posts just like they are in DB, with all of `name_en`, `title_de` columns:
70
+
71
+ ```ruby
72
+ post = Post.take
73
+ posts = Post.all
74
+ ```
75
+
76
+ For receiving columns for current locale use `.translated` method with the list of required columns:
77
+
78
+ ```ruby
79
+ post = Post.translated(:title, :name, :text)
80
+ ```
81
+
82
+ It accepts symbols and `SQL` strings that will go to `SELECT` statement.
83
+
84
+ After invoking `.translated` passed columns becomes available in querying methods:
85
+ ```ruby
86
+ Post.translated(:title, :name)
87
+ .where(title: 'smth')
88
+ .where("name ILIKE '%name%'")
89
+ .order('title DESC, name ASC')
90
+ ```
91
+
92
+ ## Fallbacks
93
+
94
+ Set up `I18n.fallbacks` in `application.rb`:
95
+
96
+ ```ruby
97
+ I18n.fallbacks = {uk: [:ru, :en]}
98
+ ```
99
+
100
+ Now ukrainian will fallback to russian and then to english.
101
+
102
+ Lets take post record:
103
+
104
+ ```ruby
105
+ Post.translated(:name).take
106
+ ```
107
+
108
+ Fallback rule will be present in produced `SQL` statement:
109
+
110
+ ```sql
111
+ COALESCE(COALESCE("posts"."name_uk", name_ru), name_en) AS name
112
+ ```
113
+
114
+ Fallbacks could be set through option of `.translated` method in model:
115
+
116
+ ```ruby
117
+ class Post
118
+ translates :name, fallback: {_: %i[name_en title_en]}
119
+ end
120
+ ```
121
+
122
+ Here `_` key means any locale.
123
+ If current locale is `ru` and `name_ru` is `NULL` then `name_en` will be used.
124
+ If it is `NULL` too then `title_en` will be received.
125
+ If current locale is `en` then `name_en` fallback rule will be ignored and `title_en` will be received.
126
+
127
+ ## Plurals
128
+
129
+ Described Post model has `slug` columns for human readable urls.
130
+ Also it has `translated` boolean columns for hiding not translated posts from users.
131
+
132
+ ```ruby
133
+ class Post < ApplicationRecord
134
+ translates :name, ..., plurals: %i[slugs translateds]
135
+ end
136
+ ```
137
+
138
+ Query for show page loads `slug` and `translated` columns for all locales:
139
+
140
+ ```ruby
141
+ post = Post.translated(:slug, :slugs, :translateds).find_by(slug: params[:slug])
142
+ ```
143
+
144
+ Now at the show page you can provide links to same post in different languages filtering out not translated:
145
+
146
+ ```erbruby
147
+ <% I18n.available_locales.each do |locale| %>
148
+ <% if @post.send("translated_#{locale}") %>
149
+ <% link_to "Read in #{locale}", post_url(@post.send("slug_#{locale}")) %>
150
+ <% end %>
151
+ <% end %>
152
+ ```
6
153
 
7
154
  ## Installation
8
155
  Add this line to your application's Gemfile:
@@ -21,8 +168,5 @@ Or install it yourself as:
21
168
  $ gem install from_clause_translate
22
169
  ```
23
170
 
24
- ## Contributing
25
- Contribution directions go here.
26
-
27
171
  ## License
28
172
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -2,14 +2,9 @@ module FromClauseTranslate
2
2
  require 'active_record'
3
3
  require 'from_clause_translate/active_record_relation'
4
4
  require 'from_clause_translate/class_methods'
5
+ require 'from_clause_translate/translation_data'
5
6
 
6
- def self.included model
7
- model.instance_variable_set :@original_connection, model.connection
8
- model.extend ClassMethods
9
- model.const_set :TRANSLATED, {}
10
- model.const_set :TRANSLATED_PLURALS, {}
11
- model.const_set :TRANSLATED_SELECTION, Hash[
12
- I18n.available_locales.map { |locale| [locale, {}] }
13
- ]
7
+ def self.included(model)
8
+ model.extend FromClauseTranslate::ClassMethods
14
9
  end
15
10
  end
@@ -1,33 +1,35 @@
1
1
  require 'from_clause_translate/translated_columns_builder'
2
2
 
3
3
  module ActiveRecord::Relation::Extended
4
- def arel aliases = nil
4
+ def arel(aliases = nil)
5
+ arel = super
5
6
  apply_translates
6
- super aliases
7
+ arel.instance_variable_get(:@ctx).source.left = @from_clause if @from_clause
8
+ arel
7
9
  end
8
10
 
9
- def add_translated_columns columns
11
+ def add_translated_columns(columns)
10
12
  (@values[:translated] ||= []).concat columns
11
13
  end
12
14
 
13
- def add_translated_column column
15
+ def add_translated_column(column)
14
16
  (@values[:translated] ||= []) << column
15
17
  end
16
18
 
17
19
  def apply_translates
18
- return if @translates_applied || !@klass.const_defined?(:TRANSLATED)
20
+ return if @translates_applied || !@values[:translated]
19
21
 
20
22
  @translates_applied = true
21
23
 
22
24
  columns = translated_columns_build
23
25
  return unless columns
24
26
 
25
- @arel = build_arel nil
26
-
27
27
  rel = unscoped.select(columns)
28
28
  rel.instance_variable_set(:@translates_applied, true)
29
29
  replace_plurals_in_projections
30
- @arel.from("(#{rel.arel.to_sql}) #{@klass.table_name}")
30
+ @from_clause = Arel::Nodes::SqlLiteral.new(
31
+ "(#{rel.arel.to_sql}) #{@klass.table_name}"
32
+ )
31
33
  end
32
34
 
33
35
  def translated_columns_build
@@ -36,7 +38,7 @@ module ActiveRecord::Relation::Extended
36
38
  ).perform
37
39
  end
38
40
 
39
- def perform_calculation operation, column_name
41
+ def perform_calculation(operation, column_name)
40
42
  return super operation, column_name if @without_projections
41
43
 
42
44
  rel = spawn
@@ -50,7 +52,7 @@ module ActiveRecord::Relation::Extended
50
52
  next unless column.is_a? String
51
53
 
52
54
  name = column[0] == '"' ? column[1...-1] : column
53
- plural = @klass::TRANSLATED_PLURALS[name.to_sym]
55
+ plural = @klass._translation_data.plurals[name.to_sym]
54
56
  column.replace plural if plural
55
57
  end
56
58
  end
@@ -1,106 +1,27 @@
1
- module ClassMethods
2
- require 'from_clause_translate/class_methods/fallbacks'
3
- include Fallbacks
4
-
5
- def translates *columns
1
+ module FromClauseTranslate::ClassMethods
2
+ def translates(*columns)
6
3
  options = columns.extract_options!
7
- filter_translated_columns(
8
- map_translated_columns(columns)
9
- ).each do |hash|
10
- column = hash[:name]
11
- self::TRANSLATED[column] = true
12
- define_translated_selection column, hash
13
- define_translated_column_methods column
14
- end
4
+ _translation_data.add_columns(columns)
15
5
  translates_plurals options[:plurals]
16
6
  end
17
7
 
18
- def translates_plurals plurals
19
- return unless plurals
20
-
21
- plurals.each do |plural|
22
- plural = plural.to_sym
23
- self::TRANSLATED[plural] = true
24
- column = plural.to_s.singularize.to_sym
25
- selection = I18n.available_locales.map do |locale|
26
- "#{quoted_table_name}.\"#{column}_#{locale}\""
27
- end.join ','
28
- self::TRANSLATED_PLURALS[plural] = selection
29
- I18n.available_locales.each do |locale|
30
- self::TRANSLATED_SELECTION[locale][plural] = selection
31
- end
8
+ def translates_plurals(plurals)
9
+ plurals && plurals.each do |plural|
10
+ _translation_data.add_plural(plural)
32
11
  end
33
12
  end
34
13
 
35
- def translates? column
36
- self::TRANSLATED[column.to_sym]
14
+ def translates?(column)
15
+ _translation_data.translates? column
37
16
  end
38
17
 
39
- def translated *columns
18
+ def translated(*columns)
40
19
  scope = current_scope || all
41
20
  scope.add_translated_columns columns
42
21
  scope
43
22
  end
44
23
 
45
- private
46
-
47
- def map_translated_columns columns
48
- columns.map! do |column|
49
- hash = column.is_a?(Hash) ? column : {name: column}
50
- translated_fallbacks_set hash
51
- hash
52
- end
53
- end
54
-
55
- def filter_translated_columns columns
56
- columns.keep_if do |hash|
57
- !translates?(hash[:name]) &&
58
- column_names.include?("#{hash[:name]}_#{I18n.locale}")
59
- end
60
- end
61
-
62
- def define_translated_selection column, hash
63
- fallback = hash[:fallback]
64
- I18n.available_locales.each do |locale|
65
- selection = "#{quoted_table_name}.\"#{column}_#{locale}\""
66
- selection = translated_fallbacks_wrap selection, fallback[locale]
67
- selection = translated_fallbacks_wrap selection, fallback[:_]
68
- self::TRANSLATED_SELECTION[locale][column] = "#{selection} AS #{column}"
69
- end
70
- end
71
-
72
- def define_translated_column_methods col
73
- col = col.to_s
74
- dashed = "#{col}_"
75
- define_translated_column_getter_and_setter col, dashed
76
- define_translated_column_changing_methods col, dashed
77
- end
78
-
79
- def define_translated_column_getter_and_setter col, dashed
80
- define_method col do
81
- @attributes.key?(col) ? self[col] : send("#{dashed}#{I18n.locale}")
82
- end
83
-
84
- define_method col + '=' do |val|
85
- send "#{dashed}#{I18n.locale}=", val
86
- end
87
- end
88
-
89
- def define_translated_column_changing_methods col, dashed
90
- define_method 'saved_change_to_' + col do
91
- send "saved_change_to_#{dashed}#{I18n.locale}"
92
- end
93
-
94
- %w[changed? before_last_save change_to_be_saved in_database].each do |suf|
95
- define_method dashed + suf do
96
- send "#{dashed}#{I18n.locale}_#{suf}"
97
- end
98
- end
99
-
100
- %w[saved_change_to will_save_change_to].each do |prefix|
101
- define_method "#{prefix}_#{col}?" do
102
- send "#{prefix}_#{dashed}#{I18n.locale}?"
103
- end
104
- end
24
+ def _translation_data
25
+ @translation_data ||= FromClauseTranslate::TranslationData.new(self)
105
26
  end
106
27
  end
@@ -0,0 +1,53 @@
1
+ class FromClauseTranslate::Fallback
2
+ attr_reader :model, :fallback
3
+
4
+ def initialize(model, hash)
5
+ @model = model
6
+ @fallback = hash[:fallback]
7
+
8
+ if fallback.nil?
9
+ create_fallback_from_i18n(hash[:name])
10
+ elsif !fallback.is_a? Hash
11
+ @fallback = {_: fallback}
12
+ end
13
+ end
14
+
15
+ def wrap(selection, column, locale)
16
+ wrap_with_fallbacks selection, fallback[locale], column, locale
17
+ wrap_with_fallbacks selection, fallback[:_], column, locale
18
+ selection
19
+ end
20
+
21
+ private
22
+
23
+ def wrap_with_fallbacks(selection, fallbacks, column, locale)
24
+ return unless fallbacks
25
+
26
+ if fallbacks.is_a? Array
27
+ fallbacks.each do |fallback|
28
+ wrap_with_fallbacks selection, fallback, column, locale
29
+ end
30
+ return
31
+ end
32
+
33
+ fallbacks = "#{model.table_name}.#{fallbacks}" if fallbacks.is_a? Symbol
34
+ return if fallbacks == "#{model.table_name}.#{column}_#{locale}"
35
+
36
+ selection.replace "COALESCE(#{selection}, #{fallbacks})"
37
+ end
38
+
39
+ def create_fallback_from_i18n(column)
40
+ if I18n.fallbacks.empty?
41
+ # invoke fallbacks generation
42
+ I18n.available_locales.each { |locale| I18n.fallbacks[locale] }
43
+ end
44
+ @fallback = {}
45
+ I18n.fallbacks.each do |locale, array|
46
+ result = []
47
+ fallback[locale] = result
48
+ array.each do |fallback|
49
+ result << "#{column}_#{fallback}" unless fallback == locale
50
+ end
51
+ end
52
+ end
53
+ end
@@ -79,9 +79,12 @@ class FromClauseTranslate::TranslatedColumnsBuilder
79
79
  next unless child.respond_to? :left
80
80
 
81
81
  left = child.left
82
- next if left.relation.table_name != @klass.table_name
82
+ if left.respond_to?(:relation) &&
83
+ left.relation.table_name != @klass.table_name
84
+ next
85
+ end
83
86
 
84
- translated_selection left.name
87
+ translated_selection child.left.name
85
88
  end
86
89
  end
87
90
  end
@@ -100,22 +103,24 @@ class FromClauseTranslate::TranslatedColumnsBuilder
100
103
 
101
104
  def add_translated_columns_from_orders
102
105
  @arel.ast.orders.each do |name|
103
- name = name.respond_to?(:expr) ? name.expr.name : name
106
+ if name.respond_to?(:expr)
107
+ name = name.expr
108
+ name = name.name if name.respond_to?(:name)
109
+ end
104
110
  translated_selection name
105
111
  end
106
112
  end
107
113
 
108
114
  def translated_selection name, original = nil
109
115
  sym = name.to_sym
110
- translates = @klass.translates? sym
116
+ translates = @klass.respond_to?(:translates?) && @klass.translates?(sym)
111
117
  @has_translated = true
112
118
  if translates
113
- return @columns << @klass::TRANSLATED_SELECTION[I18n.locale][sym]
119
+ return @columns << @klass._translation_data.selections[I18n.locale][sym]
114
120
  end
115
121
 
116
- @select_all = true if sym == :*
117
- return if @select_all || !@klass.columns_hash[name.to_s]
122
+ return unless @klass.columns_hash[name.to_s]
118
123
 
119
- @columns << (original || name)
124
+ @columns << (original ? original.to_sym : sym)
120
125
  end
121
126
  end
@@ -0,0 +1,89 @@
1
+ require 'from_clause_translate/fallback'
2
+
3
+ class FromClauseTranslate::TranslationData
4
+ attr_reader :model, :translated, :plurals, :selections
5
+
6
+ def initialize(model)
7
+ @model = model
8
+ @translated = {}
9
+ @plurals = {}
10
+ @selections = I18n.available_locales.map { |locale| [locale, {}] }.to_h
11
+ end
12
+
13
+ def translates?(column)
14
+ @translated[column.to_sym] || false
15
+ end
16
+
17
+ def add_columns(columns)
18
+ columns.each(&method(:add_column))
19
+ end
20
+
21
+ def add_column(column)
22
+ hash = column.is_a?(Hash) ? column : {name: column}
23
+
24
+ return if translates?(hash[:name]) ||
25
+ !model.column_names.include?("#{hash[:name]}_#{I18n.locale}")
26
+
27
+ column = hash[:name]
28
+ translated[column] = true
29
+
30
+ define_translated_selection column, hash
31
+
32
+ column = column.to_s
33
+ dashed = "#{column}_"
34
+ define_translated_column_getter_and_setter column, dashed
35
+ define_translated_column_changing_methods column, dashed
36
+ end
37
+
38
+ def add_plural(plural)
39
+ plural = plural.to_sym
40
+ translated[plural] = true
41
+ column = plural.to_s.singularize.to_sym
42
+ selection = I18n.available_locales.map do |locale|
43
+ "#{model.quoted_table_name}.\"#{column}_#{locale}\""
44
+ end.join ','
45
+ plurals[plural] = selection
46
+ I18n.available_locales.each do |locale|
47
+ selections[locale][plural] = selection
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def define_translated_selection(column, hash)
54
+ fallback = FromClauseTranslate::Fallback.new(model, hash)
55
+ I18n.available_locales.each do |locale|
56
+ selection = "#{model.quoted_table_name}.\"#{column}_#{locale}\""
57
+ selection = fallback.wrap selection, column, locale
58
+ selections[locale][column] = "#{selection} AS #{column}"
59
+ end
60
+ end
61
+
62
+ def define_translated_column_getter_and_setter col, dashed
63
+ model.define_method col do
64
+ @attributes.key?(col) ? self[col] : send("#{dashed}#{I18n.locale}")
65
+ end
66
+
67
+ model.define_method col + '=' do |val|
68
+ send "#{dashed}#{I18n.locale}=", val
69
+ end
70
+ end
71
+
72
+ def define_translated_column_changing_methods col, dashed
73
+ model.define_method 'saved_change_to_' + col do
74
+ send "saved_change_to_#{dashed}#{I18n.locale}"
75
+ end
76
+
77
+ %w[changed? before_last_save change_to_be_saved in_database].each do |suf|
78
+ model.define_method dashed + suf do
79
+ send "#{dashed}#{I18n.locale}_#{suf}"
80
+ end
81
+ end
82
+
83
+ %w[saved_change_to will_save_change_to].each do |prefix|
84
+ model.define_method "#{prefix}_#{col}?" do
85
+ send "#{prefix}_#{dashed}#{I18n.locale}?"
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,3 +1,3 @@
1
1
  module FromClauseTranslate
2
- VERSION = '0.2.6'.freeze
2
+ VERSION = '0.2.7'.freeze
3
3
  end
metadata CHANGED
@@ -1,29 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: from_clause_translate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Kushin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-10 00:00:00.000000000 Z
11
+ date: 2019-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5'
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: standalone_migrations
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: database_cleaner
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
27
83
  description: Translates record using SQL from clause.
28
84
  email:
29
85
  - romadzao@gmail.com
@@ -36,10 +92,11 @@ files:
36
92
  - lib/from_clause_translate.rb
37
93
  - lib/from_clause_translate/active_record_relation.rb
38
94
  - lib/from_clause_translate/class_methods.rb
39
- - lib/from_clause_translate/class_methods/fallbacks.rb
95
+ - lib/from_clause_translate/fallback.rb
40
96
  - lib/from_clause_translate/translated_columns_builder.rb
97
+ - lib/from_clause_translate/translation_data.rb
41
98
  - lib/from_clause_translate/version.rb
42
- homepage:
99
+ homepage: https://gitlab.com/romikus/rails-from-clause-translate-gem
43
100
  licenses:
44
101
  - MIT
45
102
  metadata: {}
@@ -58,8 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
115
  - !ruby/object:Gem::Version
59
116
  version: '0'
60
117
  requirements: []
61
- rubyforge_project:
62
- rubygems_version: 2.7.6
118
+ rubygems_version: 3.0.3
63
119
  signing_key:
64
120
  specification_version: 4
65
121
  summary: For database record translations
@@ -1,32 +0,0 @@
1
- module Fallbacks
2
- private
3
-
4
- def translated_fallbacks_set hash
5
- fallback = hash[:fallback]
6
- return hash[:fallback] = {} unless hash[:fallback]
7
- return if fallback.is_a? Hash
8
-
9
- hash[:fallback] = {_: fallback}
10
- end
11
-
12
- def translated_fallbacks_wrap selection, fallbacks
13
- return selection unless fallbacks
14
-
15
- if fallbacks.is_a?(String) || fallbacks.is_a?(Symbol)
16
- translated_selection_fallback_wrap selection, fallbacks
17
- else
18
- fallbacks.each do |fallback|
19
- selection = translated_selection_fallback_wrap selection, fallback
20
- end
21
- selection
22
- end
23
- end
24
-
25
- def translated_selection_fallback_wrap selection, fallback
26
- if fallback.is_a? String
27
- "COALESCE(#{selection}, #{fallback})"
28
- else
29
- "COALESCE(#{selection}, #{table_name}.#{fallback})"
30
- end
31
- end
32
- end