granite 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/granite/install_controller_generator.rb +1 -1
- data/lib/generators/granite_generator.rb +1 -1
- data/lib/granite.rb +4 -0
- data/lib/granite/action.rb +1 -10
- data/lib/granite/action/performing.rb +2 -1
- data/lib/granite/base.rb +24 -0
- data/lib/granite/represents.rb +24 -0
- data/lib/granite/represents/attribute.rb +89 -0
- data/lib/granite/represents/reflection.rb +24 -0
- data/lib/granite/translations.rb +37 -0
- data/lib/granite/version.rb +3 -0
- metadata +26 -10
- data/lib/granite/action/represents.rb +0 -26
- data/lib/granite/action/represents/attribute.rb +0 -90
- data/lib/granite/action/represents/reflection.rb +0 -15
- data/lib/granite/action/translations.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eee58f357db73ca54fa35ec5a68a13081bd450a8
|
4
|
+
data.tar.gz: 1042435a47b006d54caafc174552863a2024a52d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59143c029f08dae76509be73e06b653eedbfb29b98cf8b79ffebcd0eb0183fd63fe9312a0fa51c8d7806097e5a70d7168e87e116c45ce7e16af3211886b03ed4
|
7
|
+
data.tar.gz: f3d6579fbd80170a55a3fef47e90db59236087a0ecd4b14c1f54f145553b38bc118efd7f24a535b5d6225143511db18b26f82187bcebb3f384063c03bdc997f2
|
@@ -3,7 +3,7 @@ require 'rails/generators/base'
|
|
3
3
|
module Granite
|
4
4
|
module Generators
|
5
5
|
class InstallControllerGenerator < Rails::Generators::Base
|
6
|
-
source_root File.expand_path('
|
6
|
+
source_root File.expand_path('../../..', __dir__)
|
7
7
|
|
8
8
|
desc 'Creates a Granite::Controller for further customization'
|
9
9
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class GraniteGenerator < Rails::Generators::NamedBase
|
2
|
-
source_root File.expand_path('
|
2
|
+
source_root File.expand_path('templates', __dir__)
|
3
3
|
|
4
4
|
argument :projector, type: :string, required: false
|
5
5
|
class_option :collection, type: :boolean, aliases: '-C', desc: 'Generate collection action'
|
data/lib/granite.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_support/dependencies'
|
2
2
|
require 'action_controller'
|
3
3
|
|
4
|
+
require 'granite/version'
|
4
5
|
require 'granite/config'
|
5
6
|
require 'granite/context'
|
6
7
|
|
@@ -17,8 +18,11 @@ module Granite
|
|
17
18
|
singleton_class.delegate(*Granite::Context.delegated, to: :context)
|
18
19
|
end
|
19
20
|
|
21
|
+
require 'granite/base'
|
20
22
|
require 'granite/dispatcher'
|
21
23
|
require 'granite/action'
|
22
24
|
require 'granite/projector'
|
23
25
|
require 'granite/routing'
|
24
26
|
require 'granite/rails' if defined?(::Rails)
|
27
|
+
|
28
|
+
ActiveData.base_concern = Granite::Base
|
data/lib/granite/action.rb
CHANGED
@@ -4,14 +4,12 @@ require 'active_record/validations'
|
|
4
4
|
require 'active_support/callbacks'
|
5
5
|
|
6
6
|
require 'granite/action/types'
|
7
|
-
require 'granite/action/represents'
|
8
7
|
require 'granite/action/error'
|
9
8
|
require 'granite/action/performing'
|
10
9
|
require 'granite/action/performer'
|
11
10
|
require 'granite/action/preconditions'
|
12
11
|
require 'granite/action/policies'
|
13
12
|
require 'granite/action/projectors'
|
14
|
-
require 'granite/action/translations'
|
15
13
|
require 'granite/action/subject'
|
16
14
|
|
17
15
|
module Granite
|
@@ -41,20 +39,13 @@ module Granite
|
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
include
|
45
|
-
include ActiveData::Model
|
46
|
-
include ActiveData::Model::Representation
|
47
|
-
include ActiveData::Model::Associations
|
48
|
-
include ActiveData::Model::Dirty
|
49
|
-
include ActiveModel::Validations::Callbacks
|
42
|
+
include Base
|
50
43
|
include Performing
|
51
44
|
include Subject
|
52
45
|
include Performer
|
53
46
|
include Preconditions
|
54
47
|
include Policies
|
55
48
|
include Projectors
|
56
|
-
include Translations
|
57
|
-
include Represents
|
58
49
|
prepend AssignAttributes
|
59
50
|
|
60
51
|
handle_exception ActiveRecord::RecordInvalid do |e|
|
data/lib/granite/base.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_data/model'
|
2
|
+
require 'active_data/model/primary'
|
3
|
+
require 'active_data/model/lifecycle'
|
4
|
+
require 'active_data/model/associations'
|
5
|
+
|
6
|
+
require 'granite/translations'
|
7
|
+
require 'granite/represents'
|
8
|
+
|
9
|
+
module Granite
|
10
|
+
module Base
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
include ActiveSupport::Callbacks
|
14
|
+
include ActiveData::Model
|
15
|
+
include ActiveData::Model::Representation
|
16
|
+
include ActiveData::Model::Dirty
|
17
|
+
include ActiveData::Model::Associations
|
18
|
+
include ActiveData::Model::Primary
|
19
|
+
include ActiveModel::Validations::Callbacks
|
20
|
+
|
21
|
+
include Granite::Translations
|
22
|
+
include Granite::Represents
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'granite/represents/reflection'
|
2
|
+
|
3
|
+
module Granite
|
4
|
+
module Represents
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
private
|
9
|
+
|
10
|
+
def represents(*fields, &block)
|
11
|
+
options = fields.extract_options!.symbolize_keys
|
12
|
+
|
13
|
+
fields.each do |field|
|
14
|
+
add_attribute Granite::Represents::Reflection, field, options, &block
|
15
|
+
|
16
|
+
before_validation do
|
17
|
+
attribute(field).sync if __send__ "#{field}_changed?"
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Granite
|
2
|
+
module Represents
|
3
|
+
class Attribute < ActiveData::Model::Attributes::Attribute
|
4
|
+
delegate :writer, :reader, :reader_before_type_cast, to: :reflection
|
5
|
+
|
6
|
+
def initialize(*_args)
|
7
|
+
super
|
8
|
+
|
9
|
+
set_default_value
|
10
|
+
set_default_value_before_type_cast
|
11
|
+
end
|
12
|
+
|
13
|
+
def sync
|
14
|
+
return if reference.nil?
|
15
|
+
reference.public_send(writer, read)
|
16
|
+
end
|
17
|
+
|
18
|
+
def typecast(value)
|
19
|
+
return value if value.class == type
|
20
|
+
|
21
|
+
typecaster.call(value, self) unless value.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def type
|
25
|
+
return reflection.options[:type] if reflection.options[:type].present?
|
26
|
+
active_data_type || type_from_type_for_attribute || super
|
27
|
+
end
|
28
|
+
|
29
|
+
def typecaster
|
30
|
+
@typecaster ||= begin
|
31
|
+
type_class = type.instance_of?(Class) ? type : type.class
|
32
|
+
@typecaster = ActiveData.typecaster(type_class.ancestors.grep(Class))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def reference
|
39
|
+
owner.__send__(reflection.reference)
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_default_value
|
43
|
+
return unless reference.respond_to?(reader)
|
44
|
+
|
45
|
+
variable_cache(:value) do
|
46
|
+
normalize(enumerize(reference.public_send(reader)))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_default_value_before_type_cast
|
51
|
+
return unless reference.respond_to?(reader_before_type_cast)
|
52
|
+
|
53
|
+
variable_cache(:value_before_type_cast) do
|
54
|
+
defaultize(reference.public_send(reader_before_type_cast))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def active_data_type
|
59
|
+
return nil unless reference.is_a?(ActiveData::Model)
|
60
|
+
|
61
|
+
reference_attribute = reference.attribute(name)
|
62
|
+
|
63
|
+
return Granite::Action::Types::Collection.new(reference_attribute.type) if [
|
64
|
+
ActiveData::Model::Attributes::ReferenceMany,
|
65
|
+
ActiveData::Model::Attributes::Collection,
|
66
|
+
ActiveData::Model::Attributes::Dictionary
|
67
|
+
].any? { |klass| reference_attribute.is_a? klass }
|
68
|
+
|
69
|
+
reference_attribute.type # TODO: create `type_for_attribute` method inside of ActiveData
|
70
|
+
end
|
71
|
+
|
72
|
+
def type_from_type_for_attribute
|
73
|
+
return nil unless reference.respond_to?(:type_for_attribute)
|
74
|
+
|
75
|
+
attribute_type = reference.type_for_attribute(name.to_s)
|
76
|
+
|
77
|
+
return Granite::Action::Types::Collection.new(convert_type_to_value_class(attribute_type.subtype)) if attribute_type.respond_to?(:subtype)
|
78
|
+
|
79
|
+
convert_type_to_value_class(attribute_type)
|
80
|
+
end
|
81
|
+
|
82
|
+
def convert_type_to_value_class(attribute_type)
|
83
|
+
return attribute_type.value_class if attribute_type.respond_to?(:value_class)
|
84
|
+
|
85
|
+
ActiveData::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'granite/represents/attribute'
|
2
|
+
|
3
|
+
module Granite
|
4
|
+
module Represents
|
5
|
+
class Reflection < ActiveData::Model::Attributes::Reflections::Represents
|
6
|
+
class << self
|
7
|
+
def build(target, generated_methods, name, *args, &block)
|
8
|
+
options = args.last
|
9
|
+
|
10
|
+
reference = target.reflect_on_association(options[:of]) if target.respond_to?(:reflect_on_association)
|
11
|
+
reference ||= target.reflect_on_attribute(options[:of]) if target.respond_to?(:reflect_on_attribute)
|
12
|
+
|
13
|
+
target.validates_presence_of(reference.name) if reference
|
14
|
+
|
15
|
+
super(target, generated_methods, name, *args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def attribute_class
|
19
|
+
@attribute_class ||= Granite::Represents::Attribute
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Granite
|
2
|
+
module Translations
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def translate(*args)
|
6
|
+
I18n.translate(*self.class.scope_translation_args(args))
|
7
|
+
end
|
8
|
+
alias t translate
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def scope_translation_args(args)
|
12
|
+
options = args.extract_options!
|
13
|
+
|
14
|
+
lookups = expand_relative_key(args.first).map(&:to_sym)
|
15
|
+
lookups += [options[:default]]
|
16
|
+
lookups = lookups.flatten.compact
|
17
|
+
|
18
|
+
key = lookups.shift
|
19
|
+
options[:default] = lookups
|
20
|
+
|
21
|
+
[key, options]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def expand_relative_key(key)
|
27
|
+
return [key] unless key.is_a?(String) && key.start_with?('.')
|
28
|
+
|
29
|
+
base_key = key.sub(/^\./, '')
|
30
|
+
|
31
|
+
lookup_ancestors.map do |klass|
|
32
|
+
:"#{klass.i18n_scope}.#{klass.model_name.i18n_key}.#{base_key}"
|
33
|
+
end.flatten + [base_key]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: granite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arkadiy Zabazhanov & friends
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: active_data
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.1.
|
33
|
+
version: 1.1.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.1.
|
40
|
+
version: 1.1.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activesupport
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "<"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rspec
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -276,14 +290,11 @@ files:
|
|
276
290
|
- lib/granite/action/preconditions/base_precondition.rb
|
277
291
|
- lib/granite/action/preconditions/embedded_precondition.rb
|
278
292
|
- lib/granite/action/projectors.rb
|
279
|
-
- lib/granite/action/represents.rb
|
280
|
-
- lib/granite/action/represents/attribute.rb
|
281
|
-
- lib/granite/action/represents/reflection.rb
|
282
293
|
- lib/granite/action/subject.rb
|
283
294
|
- lib/granite/action/transaction.rb
|
284
|
-
- lib/granite/action/translations.rb
|
285
295
|
- lib/granite/action/types.rb
|
286
296
|
- lib/granite/action/types/collection.rb
|
297
|
+
- lib/granite/base.rb
|
287
298
|
- lib/granite/config.rb
|
288
299
|
- lib/granite/context.rb
|
289
300
|
- lib/granite/dispatcher.rb
|
@@ -298,6 +309,9 @@ files:
|
|
298
309
|
- lib/granite/projector/translations/helper.rb
|
299
310
|
- lib/granite/projector/translations/view_helper.rb
|
300
311
|
- lib/granite/rails.rb
|
312
|
+
- lib/granite/represents.rb
|
313
|
+
- lib/granite/represents/attribute.rb
|
314
|
+
- lib/granite/represents/reflection.rb
|
301
315
|
- lib/granite/routing.rb
|
302
316
|
- lib/granite/routing/cache.rb
|
303
317
|
- lib/granite/routing/caching.rb
|
@@ -311,6 +325,8 @@ files:
|
|
311
325
|
- lib/granite/rspec/projector_helpers.rb
|
312
326
|
- lib/granite/rspec/raise_validation_error.rb
|
313
327
|
- lib/granite/rspec/satisfy_preconditions.rb
|
328
|
+
- lib/granite/translations.rb
|
329
|
+
- lib/granite/version.rb
|
314
330
|
homepage: https://github.com/toptal/granite
|
315
331
|
licenses:
|
316
332
|
- MIT
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'granite/action/represents/reflection'
|
2
|
-
|
3
|
-
module Granite
|
4
|
-
class Action
|
5
|
-
module Represents
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
private
|
10
|
-
|
11
|
-
def represents(*fields, &block)
|
12
|
-
options = fields.extract_options!.symbolize_keys
|
13
|
-
|
14
|
-
fields.each do |field|
|
15
|
-
add_attribute Granite::Action::Represents::Reflection, field, options, &block
|
16
|
-
|
17
|
-
before_validation do
|
18
|
-
attribute(field).sync if __send__ "#{field}_changed?"
|
19
|
-
true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
module Granite
|
2
|
-
class Action
|
3
|
-
module Represents
|
4
|
-
class Attribute < ActiveData::Model::Attributes::Attribute
|
5
|
-
delegate :writer, :reader, :reader_before_type_cast, to: :reflection
|
6
|
-
|
7
|
-
def initialize(*_args)
|
8
|
-
super
|
9
|
-
|
10
|
-
set_default_value
|
11
|
-
set_default_value_before_type_cast
|
12
|
-
end
|
13
|
-
|
14
|
-
def sync
|
15
|
-
reference.public_send(writer, read)
|
16
|
-
end
|
17
|
-
|
18
|
-
def typecast(value)
|
19
|
-
return value if value.class == type
|
20
|
-
|
21
|
-
typecaster.call(value, self) unless value.nil?
|
22
|
-
end
|
23
|
-
|
24
|
-
def type
|
25
|
-
return reflection.options[:type] if reflection.options[:type].present?
|
26
|
-
active_data_type || type_from_type_for_attribute || super
|
27
|
-
end
|
28
|
-
|
29
|
-
def typecaster
|
30
|
-
@typecaster ||= begin
|
31
|
-
type_class = type.instance_of?(Class) ? type : type.class
|
32
|
-
@typecaster = ActiveData.typecaster(type_class.ancestors.grep(Class))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def reference
|
39
|
-
owner.__send__(reflection.reference)
|
40
|
-
end
|
41
|
-
|
42
|
-
def set_default_value
|
43
|
-
return unless reference.respond_to?(reader)
|
44
|
-
|
45
|
-
variable_cache(:value) do
|
46
|
-
normalize(enumerize(reference.public_send(reader)))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def set_default_value_before_type_cast
|
51
|
-
return unless reference.respond_to?(reader_before_type_cast)
|
52
|
-
|
53
|
-
variable_cache(:value_before_type_cast) do
|
54
|
-
defaultize(reference.public_send(reader_before_type_cast))
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def active_data_type
|
59
|
-
return nil unless reference.is_a?(ActiveData::Model)
|
60
|
-
|
61
|
-
reference_attribute = reference.attribute(name)
|
62
|
-
|
63
|
-
return Granite::Action::Types::Collection.new(reference_attribute.type) if [
|
64
|
-
ActiveData::Model::Attributes::ReferenceMany,
|
65
|
-
ActiveData::Model::Attributes::Collection,
|
66
|
-
ActiveData::Model::Attributes::Dictionary
|
67
|
-
].any? { |klass| reference_attribute.is_a? klass }
|
68
|
-
|
69
|
-
reference_attribute.type # TODO: create `type_for_attribute` method inside of ActiveData
|
70
|
-
end
|
71
|
-
|
72
|
-
def type_from_type_for_attribute
|
73
|
-
return nil unless reference.respond_to?(:type_for_attribute)
|
74
|
-
|
75
|
-
attribute_type = reference.type_for_attribute(name.to_s)
|
76
|
-
|
77
|
-
return Granite::Action::Types::Collection.new(convert_type_to_value_class(attribute_type.subtype)) if attribute_type.respond_to?(:subtype)
|
78
|
-
|
79
|
-
convert_type_to_value_class(attribute_type)
|
80
|
-
end
|
81
|
-
|
82
|
-
def convert_type_to_value_class(attribute_type)
|
83
|
-
return attribute_type.value_class if attribute_type.respond_to?(:value_class)
|
84
|
-
|
85
|
-
ActiveData::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'granite/action/represents/attribute'
|
2
|
-
|
3
|
-
module Granite
|
4
|
-
class Action
|
5
|
-
module Represents
|
6
|
-
class Reflection < ActiveData::Model::Attributes::Reflections::Represents
|
7
|
-
class << self
|
8
|
-
def attribute_class
|
9
|
-
@attribute_class ||= Granite::Action::Represents::Attribute
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Granite
|
2
|
-
class Action
|
3
|
-
module Translations
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
def translate(*args)
|
7
|
-
I18n.translate(*self.class.scope_translation_args(args))
|
8
|
-
end
|
9
|
-
alias t translate
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
def scope_translation_args(args)
|
13
|
-
options = args.extract_options!
|
14
|
-
|
15
|
-
lookups = expand_relative_key(args.first).map(&:to_sym)
|
16
|
-
lookups += [options[:default]]
|
17
|
-
lookups = lookups.flatten.compact
|
18
|
-
|
19
|
-
key = lookups.shift
|
20
|
-
options[:default] = lookups
|
21
|
-
|
22
|
-
[key, options]
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def expand_relative_key(key)
|
28
|
-
return [key] unless key.is_a?(String) && key.start_with?('.')
|
29
|
-
|
30
|
-
base_key = key.sub(/^\./, '')
|
31
|
-
|
32
|
-
lookup_ancestors.map do |klass|
|
33
|
-
:"#{klass.i18n_scope}.#{klass.model_name.i18n_key}.#{base_key}"
|
34
|
-
end.flatten + [base_key]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|