engine2 1.0.2 → 1.0.3
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/conf/message.yaml +7 -0
- data/conf/message_pl.yaml +7 -0
- data/engine2.gemspec +1 -1
- data/lib/engine2/action.rb +0 -5
- data/lib/engine2/core.rb +9 -8
- data/lib/engine2/handler.rb +2 -2
- data/lib/engine2/meta.rb +196 -33
- data/lib/engine2/meta/decode_meta.rb +2 -1
- data/lib/engine2/meta/form_meta.rb +3 -132
- data/lib/engine2/meta/infra_meta.rb +14 -9
- data/lib/engine2/meta/list_meta.rb +1 -4
- data/lib/engine2/meta/view_meta.rb +0 -14
- data/lib/engine2/models/UserInfo.rb +0 -4
- data/lib/engine2/scheme.rb +5 -5
- data/lib/engine2/type_info.rb +0 -1
- data/lib/engine2/version.rb +1 -1
- data/public/assets/javascripts.js +13 -13
- data/public/js/angular-animate.js +52 -20
- data/public/js/angular-cookies.js +2 -2
- data/public/js/angular-route.js +10 -7
- data/public/js/angular-sanitize.js +4 -4
- data/public/js/angular.js +322 -168
- data/public/js/lodash.custom.min.js +95 -93
- data/views/engine2.coffee +34 -29
- data/views/engine2actions.coffee +62 -60
- data/views/infra/index.slim +2 -2
- data/views/infra/inspect.slim +5 -1
- data/views/scaffold/confirm.slim +1 -1
- data/views/scaffold/list.slim +11 -23
- data/views/scaffold/message.slim +1 -1
- data/views/scaffold/search.slim +1 -2
- data/views/scaffold/view.slim +1 -1
- data/views/search_fields/checkbox2.slim +1 -1
- data/views/search_fields/checkbox_buttons.slim +3 -3
- data/views/search_fields/date_range.slim +4 -4
- data/views/search_fields/decimal_date_range.slim +4 -4
- data/views/search_fields/input_text.slim +2 -2
- data/views/search_fields/integer.slim +2 -2
- data/views/search_fields/integer_range.slim +2 -2
- data/views/search_fields/list_bsmselect.slim +2 -2
- data/views/search_fields/list_bsselect.slim +2 -2
- data/views/search_fields/list_buttons.slim +2 -2
- data/views/search_fields/list_select.slim +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c81c9b9a3857540db437d0bc5ad18bab4e420a28
|
4
|
+
data.tar.gz: 543048567b1754a90c6c286c6860181882aecd46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc5faef135f2d9e1115016345988b2eb562e2aa2cec1fc106286fc79d70c43a73da84f580aa37583816af3b2d40e28104341cb0f0fcb9491232e1841bc01088d
|
7
|
+
data.tar.gz: f6d800d24a201d967d91af602fd46918e73263f9fbd1572c525b80eada313b53967e19f010311e8be87666d06bc6485f721ff4502ef0f04b98540e5f6a1a250c
|
data/conf/message.yaml
CHANGED
data/conf/message_pl.yaml
CHANGED
data/engine2.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_dependency 'coffee-script', '~> 2.4'
|
29
29
|
|
30
30
|
spec.add_development_dependency "bundler", "~> 1.11"
|
31
|
-
spec.add_development_dependency "rake", "~>
|
31
|
+
spec.add_development_dependency "rake", "~> 11.1"
|
32
32
|
spec.add_development_dependency 'uglifier', '~> 3.0'
|
33
33
|
spec.add_development_dependency 'yui-compressor', '~> 0.12'
|
34
34
|
end
|
data/lib/engine2/action.rb
CHANGED
@@ -71,11 +71,6 @@ module Engine2
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def undefine_action name
|
75
|
-
::Kernel.raise E2Error.new("No action #{name} defined") unless @actions[name]
|
76
|
-
@actions.delete(name)
|
77
|
-
end
|
78
|
-
|
79
74
|
def define_action_bundle name, *actions
|
80
75
|
define_singleton_method!(name) do |&blk|
|
81
76
|
if blk
|
data/lib/engine2/core.rb
CHANGED
@@ -120,7 +120,7 @@ class Symbol
|
|
120
120
|
end
|
121
121
|
|
122
122
|
class << Sequel
|
123
|
-
attr_accessor :
|
123
|
+
attr_accessor :alias_columns_in_joins
|
124
124
|
|
125
125
|
def split_keys id
|
126
126
|
id.split('|')
|
@@ -147,7 +147,7 @@ end
|
|
147
147
|
Sequel.quote_identifiers = false
|
148
148
|
Sequel.extension :core_extensions
|
149
149
|
Sequel::Inflections.clear
|
150
|
-
Sequel.
|
150
|
+
Sequel.alias_columns_in_joins = true
|
151
151
|
# Sequel::Model.plugin :json_serializer, :naked => true
|
152
152
|
# Sequel::Model.plugin :timestamps
|
153
153
|
# Sequel::Model.plugin :validation_class_methods
|
@@ -364,7 +364,7 @@ module E2Model
|
|
364
364
|
# nil
|
365
365
|
else
|
366
366
|
if table != model_table_name
|
367
|
-
if Sequel.
|
367
|
+
if Sequel.alias_columns_in_joins
|
368
368
|
name.qualify(table).as(:"#{table}__#{name}")
|
369
369
|
else
|
370
370
|
name.qualify(table)
|
@@ -435,7 +435,7 @@ module Engine2
|
|
435
435
|
PATH ||= File.expand_path('../..', File.dirname(__FILE__))
|
436
436
|
|
437
437
|
class << self
|
438
|
-
attr_reader :app, :reloading
|
438
|
+
attr_reader :app, :app_name, :reloading
|
439
439
|
attr_reader :core_loaded
|
440
440
|
|
441
441
|
def database name
|
@@ -457,8 +457,8 @@ module Engine2
|
|
457
457
|
|
458
458
|
def bootstrap_e2db
|
459
459
|
e2_db_file = (defined? JRUBY_VERSION) ? "jdbc:sqlite:#{@app}/engine2.db" : "sqlite://#{@app}/engine2.db"
|
460
|
-
|
461
|
-
|
460
|
+
const_set :E2DB, connect(e2_db_file, loggers: [Logger.new($stdout)], convert_types: false, name: :engine2)
|
461
|
+
const_set :DUMMYDB, Sequel::Database.new(uri: 'dummy')
|
462
462
|
def DUMMYDB.synchronize *args;end
|
463
463
|
end
|
464
464
|
|
@@ -482,8 +482,8 @@ module Engine2
|
|
482
482
|
puts "MODELS: #{Sequel::DATABASES.reduce(0){|s, d|s + d.models.size}}, Time: #{Time.now - t}"
|
483
483
|
Sequel::DATABASES.each &:dump_schema_cache_to_file
|
484
484
|
|
485
|
-
|
486
|
-
|
485
|
+
send(:remove_const, :ROOT) if defined? ROOT
|
486
|
+
const_set(:ROOT, Action.new(nil, :api, RootMeta, {}))
|
487
487
|
|
488
488
|
@boot_blk.(ROOT)
|
489
489
|
ROOT.setup_action_tree
|
@@ -492,6 +492,7 @@ module Engine2
|
|
492
492
|
|
493
493
|
def bootstrap app, opts = {}
|
494
494
|
@app = app
|
495
|
+
@app_name = opts[:name] || File::basename(app)
|
495
496
|
@reloading = opts[:reloading]
|
496
497
|
bootstrap_e2db
|
497
498
|
|
data/lib/engine2/handler.rb
CHANGED
@@ -30,7 +30,7 @@ module Engine2
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def permit access
|
33
|
-
halt_forbidden
|
33
|
+
settings.development? ? raise(E2Error.new("Permission denied")) : halt_forbidden('Permission denied') unless access
|
34
34
|
end
|
35
35
|
|
36
36
|
def initial?
|
@@ -113,7 +113,7 @@ module Engine2
|
|
113
113
|
get '/*' do |name|
|
114
114
|
headers 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0'
|
115
115
|
if name.empty?
|
116
|
-
if settings.
|
116
|
+
if settings.development?
|
117
117
|
load('engine2.rb') if Engine2::reloading
|
118
118
|
Engine2::reload
|
119
119
|
end
|
data/lib/engine2/meta.rb
CHANGED
@@ -26,10 +26,6 @@ module Engine2
|
|
26
26
|
@static = static
|
27
27
|
end
|
28
28
|
|
29
|
-
# def self.method_added name
|
30
|
-
# puts "ADDED #{name}"
|
31
|
-
# end
|
32
|
-
|
33
29
|
def http_method
|
34
30
|
@http_method # || (raise E2Error.new("No http method for meta #{self.class}"))
|
35
31
|
end
|
@@ -47,22 +43,14 @@ module Engine2
|
|
47
43
|
meta = self.class.new(action, assets, self)
|
48
44
|
meta.instance_exec(handler, *meta.request_meta_proc_params(handler), &rmp)
|
49
45
|
meta.post_process
|
50
|
-
|
51
|
-
|
46
|
+
response = meta.invoke(handler)
|
47
|
+
response[:meta] = meta.get
|
48
|
+
response
|
52
49
|
else
|
53
|
-
|
54
|
-
if response.is_a?(Hash)
|
55
|
-
{response: response}
|
56
|
-
else
|
57
|
-
response
|
58
|
-
end
|
50
|
+
invoke(handler)
|
59
51
|
end
|
60
52
|
end
|
61
53
|
|
62
|
-
def response args
|
63
|
-
(@meta[:response] ||= {}).merge!(args)
|
64
|
-
end
|
65
|
-
|
66
54
|
def get
|
67
55
|
@meta
|
68
56
|
end
|
@@ -142,6 +130,14 @@ module Engine2
|
|
142
130
|
meta_type :dummy
|
143
131
|
end
|
144
132
|
|
133
|
+
class RootMeta < Meta
|
134
|
+
def initialize *args
|
135
|
+
super
|
136
|
+
@meta[:environment] = Handler::environment
|
137
|
+
@meta[:application] = Engine2::app_name
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
145
141
|
module MetaAPISupport
|
146
142
|
def reload_routes!
|
147
143
|
@meta[:reload_routes] = true
|
@@ -158,16 +154,12 @@ module Engine2
|
|
158
154
|
def info! *fields, options
|
159
155
|
raise E2Error.new("No fields given to info") if fields.empty?
|
160
156
|
fields.each do |field|
|
161
|
-
|
162
|
-
(info[field] ||= {}).merge! options # rmerge ?
|
163
|
-
else
|
164
|
-
info[field] = false
|
165
|
-
end
|
157
|
+
(info[field] ||= {}).merge! options # rmerge ?
|
166
158
|
end
|
167
159
|
end
|
168
160
|
|
169
161
|
def loc! hash
|
170
|
-
|
162
|
+
(@meta[:loc] ||= {}).merge! hash
|
171
163
|
end
|
172
164
|
|
173
165
|
def decorate list
|
@@ -202,6 +194,10 @@ module Engine2
|
|
202
194
|
@menus[menu_name]
|
203
195
|
end
|
204
196
|
|
197
|
+
def menu? menu_name
|
198
|
+
@menus && @menus[menu_name]
|
199
|
+
end
|
200
|
+
|
205
201
|
def post_process
|
206
202
|
super
|
207
203
|
if @menus && !@menus.empty?
|
@@ -356,6 +352,10 @@ module Engine2
|
|
356
352
|
end
|
357
353
|
end
|
358
354
|
|
355
|
+
def find_record handler, id
|
356
|
+
get_query[assets[:model].primary_keys_hash_qualified(split_keys(id))]
|
357
|
+
end
|
358
|
+
|
359
359
|
def select *args, &blk
|
360
360
|
assets[:model].select(*args, &blk).ensure_primary_key.setup! (@meta[:fields] = [])
|
361
361
|
end
|
@@ -424,7 +424,7 @@ module Engine2
|
|
424
424
|
panel_panel_template 'menu_m' unless panel[:panel_template] == false
|
425
425
|
# modal_action false if panel[:panel_template] == false
|
426
426
|
panel_class '' unless panel[:class]
|
427
|
-
|
427
|
+
panel_footer true if panel[:footer] != false && menu?(:panel_menu)
|
428
428
|
end
|
429
429
|
end
|
430
430
|
|
@@ -452,7 +452,7 @@ module Engine2
|
|
452
452
|
panel[:title] = tle
|
453
453
|
end
|
454
454
|
|
455
|
-
def
|
455
|
+
def panel_footer ftr
|
456
456
|
panel[:footer] = ftr
|
457
457
|
end
|
458
458
|
end
|
@@ -470,6 +470,10 @@ module Engine2
|
|
470
470
|
include MetaPanelSupport, MetaMenuSupport
|
471
471
|
meta_type :confirm
|
472
472
|
|
473
|
+
def message msg
|
474
|
+
@meta[:message] = msg
|
475
|
+
end
|
476
|
+
|
473
477
|
def pre_run
|
474
478
|
super
|
475
479
|
panel_template 'scaffold/message'
|
@@ -477,7 +481,7 @@ module Engine2
|
|
477
481
|
panel_class 'modal-default'
|
478
482
|
|
479
483
|
menu :panel_menu do
|
480
|
-
option :approve, icon: "ok", loc: LOCS[:ok], disabled: 'action.action_pending'
|
484
|
+
option :approve, icon: "ok", loc: LOCS[:ok], disabled: 'action.action_pending()'
|
481
485
|
option :cancel, icon: "remove"
|
482
486
|
end
|
483
487
|
end
|
@@ -544,15 +548,14 @@ module Engine2
|
|
544
548
|
super
|
545
549
|
config.merge!(per_page: 10, use_count: false, show_item_menu: true, selectable: true) # search_active: false,
|
546
550
|
|
547
|
-
# modal_action self.class != ListMeta
|
548
551
|
panel_template 'scaffold/list'
|
549
552
|
panel_panel_template 'panels/menu_m' unless action.parent.*.assets[:model]
|
550
553
|
search_template 'scaffold/search'
|
551
554
|
panel_title "#{:list.icon} #{LOCS[assets[:model].name.to_sym]}"
|
552
|
-
|
555
|
+
loc! LOCS[:list_locs]
|
553
556
|
menu :menu do
|
554
557
|
properties break: 2, group_class: "btn-group-xs"
|
555
|
-
option :search_toggle, icon: "search", show: "action.meta.search_fields",
|
558
|
+
option :search_toggle, icon: "search", show: "action.meta.search_fields", active: "action.ui_state.search_active", button_loc: false
|
556
559
|
# divider
|
557
560
|
option :refresh, icon: "refresh", button_loc: false
|
558
561
|
option :default_order, icon: "signal", button_loc: false
|
@@ -572,7 +575,7 @@ module Engine2
|
|
572
575
|
def select_toggle_menu
|
573
576
|
m = menu :menu
|
574
577
|
unless m.option_index(:select_toggle, false)
|
575
|
-
m.option_after :default_order, :select_toggle, icon: "check", enabled: "action.meta.config.selectable", button_loc: false
|
578
|
+
m.option_after :default_order, :select_toggle, icon: "check", enabled: "action.meta.config.selectable", active: "action.selection", button_loc: false
|
576
579
|
end
|
577
580
|
end
|
578
581
|
|
@@ -725,7 +728,7 @@ module Engine2
|
|
725
728
|
def invoke handler
|
726
729
|
json = handler.post_to_json
|
727
730
|
record = allocate_record(handler, json)
|
728
|
-
validate_and_approve(handler, record, json) ? static.record(handler, record) : {record
|
731
|
+
validate_and_approve(handler, record, json) ? static.record(handler, record) : {record!: record.to_hash, errors!: record.errors}
|
729
732
|
end
|
730
733
|
|
731
734
|
def validate name, &blk
|
@@ -747,6 +750,154 @@ module Engine2
|
|
747
750
|
end
|
748
751
|
end
|
749
752
|
|
753
|
+
module MetaFormSupport
|
754
|
+
include MetaModelSupport, MetaAPISupport, MetaTabSupport, MetaPanelSupport, MetaMenuSupport, MetaAngularSupport, MetaOnChangeSupport
|
755
|
+
|
756
|
+
def field_template template
|
757
|
+
panel[:field_template] = template
|
758
|
+
end
|
759
|
+
|
760
|
+
def pre_run
|
761
|
+
super
|
762
|
+
panel_template 'scaffold/form'
|
763
|
+
field_template 'scaffold/fields'
|
764
|
+
panel_class 'modal-large'
|
765
|
+
|
766
|
+
menu :panel_menu do
|
767
|
+
option :approve, icon: "ok", disabled: 'action.action_pending()' # text: true,
|
768
|
+
option :cancel, icon: "remove" # text: true,
|
769
|
+
end
|
770
|
+
# modal_action false
|
771
|
+
end
|
772
|
+
|
773
|
+
def record handler, record
|
774
|
+
end
|
775
|
+
|
776
|
+
def post_process
|
777
|
+
if fields = @meta[:fields]
|
778
|
+
fields = fields - static.get[:fields] if dynamic?
|
779
|
+
|
780
|
+
decorate(fields)
|
781
|
+
|
782
|
+
fields.each do |name|
|
783
|
+
# type_info = model.type_info.fetch(name)
|
784
|
+
type_info = get_type_info(name)
|
785
|
+
|
786
|
+
info[name][:render] ||= begin
|
787
|
+
renderer = DefaultFormRenderers[type_info[:type]] # .merge(default: true)
|
788
|
+
raise E2Error.new("No form renderer found for field '#{type_info[:name]}' of type '#{type_info[:type]}'") unless renderer
|
789
|
+
renderer.(self, type_info)
|
790
|
+
end
|
791
|
+
|
792
|
+
proc = FormRendererPostProcessors[type_info[:type]]
|
793
|
+
proc.(self, name, type_info) if proc
|
794
|
+
end
|
795
|
+
|
796
|
+
assoc = assets[:assoc]
|
797
|
+
if assoc && assoc[:type] == :one_to_many
|
798
|
+
# fields.select{|f| assoc[:keys].include? f}.each do |key|
|
799
|
+
# # hide_fields(key) if self[:info, key, :hidden] == nil
|
800
|
+
# info! key, disabled: true
|
801
|
+
# end
|
802
|
+
assoc[:keys].each do |key|
|
803
|
+
info! key, disabled: true if fields.include? key
|
804
|
+
end
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
super
|
809
|
+
end
|
810
|
+
|
811
|
+
def post_run
|
812
|
+
super
|
813
|
+
@meta[:primary_fields] = assets[:model].primary_keys
|
814
|
+
end
|
815
|
+
|
816
|
+
def template
|
817
|
+
Templates
|
818
|
+
end
|
819
|
+
|
820
|
+
def hr_after field, message = '-'
|
821
|
+
info! field, hr: message
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
module MetaCreateSupport
|
826
|
+
include MetaFormSupport
|
827
|
+
|
828
|
+
def self.included meta
|
829
|
+
meta.meta_type :create
|
830
|
+
end
|
831
|
+
|
832
|
+
def pre_run
|
833
|
+
super
|
834
|
+
panel_title LOCS[:create_title]
|
835
|
+
action.parent.*.menu(:menu).option_at 0, action.name, icon: "plus-sign", button_loc: false
|
836
|
+
|
837
|
+
hide_pk unless assets[:model].natural_key
|
838
|
+
end
|
839
|
+
|
840
|
+
def record handler, record
|
841
|
+
create_record(handler, record)
|
842
|
+
end
|
843
|
+
|
844
|
+
def create_record handler, record
|
845
|
+
end
|
846
|
+
|
847
|
+
def invoke handler
|
848
|
+
record = {}
|
849
|
+
if assoc = assets[:assoc]
|
850
|
+
case assoc[:type]
|
851
|
+
when :one_to_many
|
852
|
+
handler.permit parent = handler.params[:parent_id]
|
853
|
+
assoc[:keys].zip(split_keys(parent)).each{|key, val| record[key] = val}
|
854
|
+
end
|
855
|
+
end
|
856
|
+
static.record(handler, record)
|
857
|
+
{record: record, new: true}
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
module MetaModifySupport
|
862
|
+
include MetaFormSupport
|
863
|
+
|
864
|
+
def self.included meta
|
865
|
+
meta.meta_type :modify
|
866
|
+
end
|
867
|
+
|
868
|
+
def pre_run
|
869
|
+
super
|
870
|
+
panel_title LOCS[:modify_title]
|
871
|
+
action.parent.*.menu(:item_menu).option action.name, icon: "pencil", button_loc: false
|
872
|
+
end
|
873
|
+
|
874
|
+
def record handler, record
|
875
|
+
modify_record(handler, record)
|
876
|
+
end
|
877
|
+
|
878
|
+
def modify_record handler, record
|
879
|
+
end
|
880
|
+
|
881
|
+
def invoke handler
|
882
|
+
handler.permit id = handler.params[:id]
|
883
|
+
record = find_record(handler, id)
|
884
|
+
|
885
|
+
if record
|
886
|
+
static.record(handler, record)
|
887
|
+
{record: record}
|
888
|
+
else
|
889
|
+
handler.halt_not_found LOCS[:no_entry]
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
def post_run
|
894
|
+
super
|
895
|
+
assets[:model].primary_keys.each do |key| # pre_run ?
|
896
|
+
info! key, disabled: true
|
897
|
+
end
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
750
901
|
module MetaViewSupport
|
751
902
|
include MetaModelSupport, MetaAPISupport, MetaTabSupport, MetaPanelSupport, MetaMenuSupport
|
752
903
|
|
@@ -763,6 +914,20 @@ module Engine2
|
|
763
914
|
action.parent.*.menu(:item_menu).option action.name, icon: "file", button_loc: false
|
764
915
|
end
|
765
916
|
|
917
|
+
def record handler, record
|
918
|
+
end
|
919
|
+
|
920
|
+
def invoke handler
|
921
|
+
handler.permit id = handler.params[:id]
|
922
|
+
record = find_record(handler, id)
|
923
|
+
if record
|
924
|
+
static.record(handler, record)
|
925
|
+
{record: record}
|
926
|
+
else
|
927
|
+
handler.halt_not_found LOCS[:no_entry]
|
928
|
+
end
|
929
|
+
end
|
930
|
+
|
766
931
|
def post_process
|
767
932
|
if fields = @meta[:fields]
|
768
933
|
fields = fields - static.get[:fields] if dynamic?
|
@@ -850,7 +1015,6 @@ module Engine2
|
|
850
1015
|
field_info[:assoc] = :"#{info[:assoc_name]}!"
|
851
1016
|
field_info[:fields] = info[:keys]
|
852
1017
|
field_info[:type] = info[:otype]
|
853
|
-
# field_info[:table_loc] = LOCS[info[:assoc_name]]
|
854
1018
|
|
855
1019
|
(info[:keys] - [field]).each do |of|
|
856
1020
|
f_info = meta.info.fetch(of)
|
@@ -919,7 +1083,6 @@ module Engine2
|
|
919
1083
|
field_info[:assoc] = :"#{info[:assoc_name]}!"
|
920
1084
|
field_info[:fields] = keys
|
921
1085
|
field_info[:type] = info[:otype]
|
922
|
-
# field_info[:table_loc] = LOCS[info[:assoc_name]]
|
923
1086
|
|
924
1087
|
(keys - [field]).each do |of|
|
925
1088
|
f_info = meta.info[of]
|
@@ -972,7 +1135,7 @@ module Engine2
|
|
972
1135
|
end
|
973
1136
|
},
|
974
1137
|
star_to_many_field: lambda{|meta, info| Templates.scaffold},
|
975
|
-
many_to_one: lambda{|meta, info|
|
1138
|
+
many_to_one: lambda{|meta, info|
|
976
1139
|
tmpl_type = info[:decode][:form]
|
977
1140
|
case
|
978
1141
|
when tmpl_type[:scaffold]; Templates.scaffold_picker
|