agile_rails 0.0.0.1
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 +7 -0
- data/CHANGELOG.md +5 -0
- data/MIT-LICENSE +20 -0
- data/README.md +285 -0
- data/Rakefile +39 -0
- data/agile_rails.gemspec +36 -0
- data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
- data/app/assets/images/32px.png +0 -0
- data/app/assets/images/throbber.gif +0 -0
- data/app/assets/javascripts/agile/agile.js +1489 -0
- data/app/assets/javascripts/agile/jquery-migrate.js +702 -0
- data/app/assets/javascripts/agile/jquery.bpopup.js +372 -0
- data/app/assets/javascripts/agile/jquery.datetimepicker.js +1353 -0
- data/app/assets/javascripts/agile/jstree.min.js +6 -0
- data/app/assets/javascripts/agile/select-multiple.js +459 -0
- data/app/assets/javascripts/agile/some_scripts.js +33 -0
- data/app/assets/javascripts/agile.js +22 -0
- data/app/assets/javascripts/agile_application.js +22 -0
- data/app/assets/javascripts/agile_editor.js +22 -0
- data/app/assets/stylesheets/agile/agile.css +1882 -0
- data/app/assets/stylesheets/agile/agile_apps.css +149 -0
- data/app/assets/stylesheets/agile/jquery.datetimepicker.css +304 -0
- data/app/assets/stylesheets/agile/jstree.css +1107 -0
- data/app/assets/stylesheets/agile/select-multiple.css +110 -0
- data/app/assets/stylesheets/agile/th-bg.png +0 -0
- data/app/assets/stylesheets/agile/theme.css +49 -0
- data/app/assets/stylesheets/agile.css +21 -0
- data/app/assets/stylesheets/agile_application.css +20 -0
- data/app/assets/stylesheets/agile_editor.css +19 -0
- data/app/controllers/agile_application_controller.rb +735 -0
- data/app/controllers/agile_common_controller.rb +345 -0
- data/app/controllers/agile_controller.rb +977 -0
- data/app/controllers/agile_main_controller.rb +36 -0
- data/app/controls/agile_control.rb +120 -0
- data/app/controls/agile_report.rb +364 -0
- data/app/controls/ar_category_control.rb +39 -0
- data/app/controls/ar_help_control.rb +139 -0
- data/app/controls/ar_image_control.rb +180 -0
- data/app/controls/ar_journal_control.rb +47 -0
- data/app/controls/ar_menu_item_control.rb +55 -0
- data/app/controls/ar_page_control.rb +64 -0
- data/app/controls/ar_poll_result_control.rb +84 -0
- data/app/controls/ar_setup_control.rb +62 -0
- data/app/controls/belongs_to_control.rb +61 -0
- data/app/controls/browse_models_control.rb +98 -0
- data/app/controls/settings_form_control.rb +137 -0
- data/app/forms/agile_help.yml +112 -0
- data/app/forms/agile_menu.yml +140 -0
- data/app/forms/agile_report_defaults.yml +39 -0
- data/app/forms/all_options.yml +810 -0
- data/app/forms/ar_ad.yml +121 -0
- data/app/forms/ar_big_table.yml +60 -0
- data/app/forms/ar_big_table_value.yml +52 -0
- data/app/forms/ar_browse_fields.yml +35 -0
- data/app/forms/ar_browse_models.yml +48 -0
- data/app/forms/ar_category.yml +73 -0
- data/app/forms/ar_category_as_tree.yml +31 -0
- data/app/forms/ar_design.yml +75 -0
- data/app/forms/ar_filter.yml +52 -0
- data/app/forms/ar_folder_permission.yml +56 -0
- data/app/forms/ar_folder_rule.yml +48 -0
- data/app/forms/ar_gallery.yml +55 -0
- data/app/forms/ar_image.yml +126 -0
- data/app/forms/ar_image_search.yml +83 -0
- data/app/forms/ar_journal.yml +76 -0
- data/app/forms/ar_json_ld.yml +56 -0
- data/app/forms/ar_key_value.yml +33 -0
- data/app/forms/ar_key_value_store.yml +33 -0
- data/app/forms/ar_link.yml +60 -0
- data/app/forms/ar_menu.yml +67 -0
- data/app/forms/ar_menu_item.yml +141 -0
- data/app/forms/ar_page.yml +187 -0
- data/app/forms/ar_part.yml +91 -0
- data/app/forms/ar_permission.yml +52 -0
- data/app/forms/ar_permission_rule.yml +40 -0
- data/app/forms/ar_piece.yml +106 -0
- data/app/forms/ar_policy.yml +64 -0
- data/app/forms/ar_policy_rule.yml +42 -0
- data/app/forms/ar_policy_rule_nocms.yml +40 -0
- data/app/forms/ar_poll.yml +118 -0
- data/app/forms/ar_poll_item.yml +78 -0
- data/app/forms/ar_poll_result.yml +88 -0
- data/app/forms/ar_poll_result_export.yml +35 -0
- data/app/forms/ar_removed_url.yml +41 -0
- data/app/forms/ar_role.yml +43 -0
- data/app/forms/ar_seo.yml +32 -0
- data/app/forms/ar_setup.yml +45 -0
- data/app/forms/ar_site.yml +149 -0
- data/app/forms/ar_steps_template.yml +51 -0
- data/app/forms/ar_user.yml +140 -0
- data/app/forms/ar_user_role.yml +57 -0
- data/app/forms/help/dc_category_as_tree.en +4 -0
- data/app/forms/help/dc_category_as_tree.sl +5 -0
- data/app/forms/json_ld_schema.yml +168 -0
- data/app/helpers/agile_application_helper.rb +1162 -0
- data/app/helpers/agile_category_helper.rb +128 -0
- data/app/helpers/agile_common_helper.rb +308 -0
- data/app/helpers/agile_edit_helper.rb +645 -0
- data/app/helpers/agile_helper.rb +509 -0
- data/app/helpers/agile_index_helper.rb +677 -0
- data/app/helpers/ar_image_helper.rb +128 -0
- data/app/models/agile_form_fields/action.rb +61 -0
- data/app/models/agile_form_fields/agile_form_field.rb +322 -0
- data/app/models/agile_form_fields/belongs_to.rb +112 -0
- data/app/models/agile_form_fields/check_box.rb +73 -0
- data/app/models/agile_form_fields/comment.rb +62 -0
- data/app/models/agile_form_fields/date_picker.rb +104 -0
- data/app/models/agile_form_fields/date_select.rb +68 -0
- data/app/models/agile_form_fields/datetime_picker.rb +88 -0
- data/app/models/agile_form_fields/datetime_select.rb +73 -0
- data/app/models/agile_form_fields/file_field.rb +52 -0
- data/app/models/agile_form_fields/file_select.rb +69 -0
- data/app/models/agile_form_fields/hidden_field.rb +51 -0
- data/app/models/agile_form_fields/html_field.rb +69 -0
- data/app/models/agile_form_fields/journal_diff.rb +62 -0
- data/app/models/agile_form_fields/link_to.rb +69 -0
- data/app/models/agile_form_fields/method.rb +66 -0
- data/app/models/agile_form_fields/multitext_autocomplete.rb +215 -0
- data/app/models/agile_form_fields/number_field.rb +92 -0
- data/app/models/agile_form_fields/password_field.rb +63 -0
- data/app/models/agile_form_fields/radio_button.rb +95 -0
- data/app/models/agile_form_fields/readonly.rb +77 -0
- data/app/models/agile_form_fields/select.rb +281 -0
- data/app/models/agile_form_fields/submit_tag.rb +58 -0
- data/app/models/agile_form_fields/text_area.rb +61 -0
- data/app/models/agile_form_fields/text_autocomplete.rb +171 -0
- data/app/models/agile_form_fields/text_field.rb +55 -0
- data/app/models/agile_form_fields/text_with_select.rb +94 -0
- data/app/models/agile_form_fields/tree_select.rb +170 -0
- data/app/models/ar_big_table.rb +82 -0
- data/app/models/ar_big_table_value.rb +53 -0
- data/app/models/ar_category.rb +109 -0
- data/app/models/ar_design.rb +116 -0
- data/app/models/ar_filter.rb +200 -0
- data/app/models/ar_folder_permission.rb +50 -0
- data/app/models/ar_folder_rule.rb +47 -0
- data/app/models/ar_gallery.rb +53 -0
- data/app/models/ar_image.rb +198 -0
- data/app/models/ar_internals.rb +60 -0
- data/app/models/ar_journal.rb +46 -0
- data/app/models/ar_json_ld.rb +131 -0
- data/app/models/ar_key_value_store.rb +128 -0
- data/app/models/ar_link.rb +48 -0
- data/app/models/ar_memory.rb +172 -0
- data/app/models/ar_menu.rb +144 -0
- data/app/models/ar_menu_item.rb +106 -0
- data/app/models/ar_page.rb +74 -0
- data/app/models/ar_part.rb +66 -0
- data/app/models/ar_permission.rb +180 -0
- data/app/models/ar_permission_rule.rb +65 -0
- data/app/models/ar_policy.rb +78 -0
- data/app/models/ar_policy_rule.rb +65 -0
- data/app/models/ar_poll.rb +74 -0
- data/app/models/ar_poll_item.rb +47 -0
- data/app/models/ar_poll_result.rb +38 -0
- data/app/models/ar_removed_url.rb +42 -0
- data/app/models/ar_role.rb +84 -0
- data/app/models/ar_setup.rb +115 -0
- data/app/models/ar_site.rb +68 -0
- data/app/models/ar_temp.rb +150 -0
- data/app/models/ar_user.rb +72 -0
- data/app/models/ar_user_group.rb +38 -0
- data/app/models/ar_user_role.rb +54 -0
- data/app/models/ar_visit.rb +41 -0
- data/app/models/concerns/ar_page_concern.rb +128 -0
- data/app/models/concerns/ar_part_concern.rb +48 -0
- data/app/models/concerns/ar_piece_concern.rb +48 -0
- data/app/models/concerns/ar_policy_rule_concern.rb +87 -0
- data/app/models/concerns/ar_seo_concern.rb +66 -0
- data/app/models/concerns/ar_site_concern.rb +103 -0
- data/app/models/concerns/ar_user_concern.rb +195 -0
- data/app/renderers/agile_common_renderer.rb +93 -0
- data/app/renderers/agile_renderer.rb +59 -0
- data/app/renderers/ar_ad_renderer.rb +219 -0
- data/app/renderers/ar_captcha_renderer.rb +113 -0
- data/app/renderers/ar_common_renderer.rb +90 -0
- data/app/renderers/ar_gallery_renderer.rb +107 -0
- data/app/renderers/ar_menu_renderer.rb +195 -0
- data/app/renderers/ar_page_renderer.rb +147 -0
- data/app/renderers/ar_part_renderer.rb +235 -0
- data/app/renderers/ar_piece_renderer.rb +119 -0
- data/app/renderers/ar_poll_renderer.rb +272 -0
- data/app/views/agile/_edit_stuff.html.erb +57 -0
- data/app/views/agile/_form.html.erb +24 -0
- data/app/views/agile/_result.html.erb +28 -0
- data/app/views/agile/edit.html.erb +13 -0
- data/app/views/agile/error.html.erb +2 -0
- data/app/views/agile/index.html.erb +14 -0
- data/app/views/agile/login.html.erb +19 -0
- data/app/views/agile/new.html.erb +12 -0
- data/app/views/agile_common/_help.html.erb +18 -0
- data/app/views/agile_common/_iframe_edit.html.erb +2 -0
- data/app/views/agile_common/paste_clipboard.html.erb +17 -0
- data/app/views/layouts/agile.html.erb +17 -0
- data/app/views/layouts/content.html.erb +20 -0
- data/app/views/models/dump_models.html.erb +47 -0
- data/config/initializers/kaminari_patch.rb +56 -0
- data/config/locales/agile_de.yml +138 -0
- data/config/locales/agile_en.yml +162 -0
- data/config/locales/agile_sl.yml +163 -0
- data/config/locales/datetimepicker.yml +19 -0
- data/config/locales/de.yml +231 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/kaminari.yml +26 -0
- data/config/locales/models_en.yml +1032 -0
- data/config/locales/models_sl.yml +1065 -0
- data/config/locales/sl.yml +211 -0
- data/db/migrate/20240120160001_add_sessions_table.rb +12 -0
- data/db/migrate/20240120160002_ar_big_table.rb +17 -0
- data/db/migrate/20240120160003_ar_big_table_value.rb +18 -0
- data/db/migrate/20240120160004_ar_category.rb +22 -0
- data/db/migrate/20240120160005_ar_design.rb +20 -0
- data/db/migrate/20240120160006_ar_filter.rb +17 -0
- data/db/migrate/20240120160007_ar_gallery.rb +21 -0
- data/db/migrate/20240120160008_ar_journal.rb +19 -0
- data/db/migrate/20240120160009_ar_key_value_store.rb +11 -0
- data/db/migrate/20240120160010_ar_link.rb +19 -0
- data/db/migrate/20240120160011_ar_memory.rb +8 -0
- data/db/migrate/20240120160012_ar_menu.rb +21 -0
- data/db/migrate/20240120160013_ar_menu_item.rb +28 -0
- data/db/migrate/20240120160014_ar_page.rb +50 -0
- data/db/migrate/20240120160015_ar_part.rb +33 -0
- data/db/migrate/20240120160016_ar_permission.rb +16 -0
- data/db/migrate/20240120160017_ar_permission_rule.rb +17 -0
- data/db/migrate/20240120160018_ar_piece.rb +28 -0
- data/db/migrate/20240120160019_ar_policy.rb +21 -0
- data/db/migrate/20240120160020_ar_policy_rule.rb +18 -0
- data/db/migrate/20240120160021_ar_poll.rb +27 -0
- data/db/migrate/20240120160022_ar_poll_item.rb +23 -0
- data/db/migrate/20240120160023_ar_poll_result.rb +14 -0
- data/db/migrate/20240120160024_ar_removed_url.rb +16 -0
- data/db/migrate/20240120160025_ar_role.rb +17 -0
- data/db/migrate/20240120160026_ar_site.rb +37 -0
- data/db/migrate/20240120160027_ar_temp.rb +11 -0
- data/db/migrate/20240120160028_ar_user.rb +42 -0
- data/db/migrate/20240120160029_ar_user_group.rb +12 -0
- data/db/migrate/20240120160030_ar_user_role.rb +18 -0
- data/db/migrate/20240120160031_ar_visit.rb +15 -0
- data/db/migrate/20240703016001_ar_setup.rb +16 -0
- data/db/migrate/20240703016002_ar_folder_permission.rb +15 -0
- data/db/migrate/20240703016003_ar_folder_rule.rb +14 -0
- data/db/migrate/20250115000001_ar_image.rb +25 -0
- data/lib/agile/configuration.rb +43 -0
- data/lib/agile/engine.rb +29 -0
- data/lib/agile/version.rb +27 -0
- data/lib/agile.rb +282 -0
- data/lib/agile_rails.rb +1 -0
- data/lib/generators/agile/USAGE +11 -0
- data/lib/generators/agile/new_form_generator.rb +369 -0
- data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
- data/lib/tasks/agile_db_clone.rake +132 -0
- data/lib/tasks/agile_db_export_to_yaml.rake +37 -0
- data/lib/tasks/agile_db_migrate.rake +35 -0
- metadata +414 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
Description:
|
2
|
+
agile:new_form generator will create Agile Rails form from model description.
|
3
|
+
Options:
|
4
|
+
--extra: Will create some extra commented code for help default: --no-extra
|
5
|
+
--tabs: Will create form entry fields with tabs default: --no-tabs
|
6
|
+
|
7
|
+
Example:
|
8
|
+
rails generate agile:new_form model_name
|
9
|
+
|
10
|
+
This will create:
|
11
|
+
forms/model_name.yml
|
@@ -0,0 +1,369 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2024+ Damjan Rems
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Agile
|
25
|
+
module Generators
|
26
|
+
|
27
|
+
# rails g agile_rails:new_form MODEL
|
28
|
+
class NewFormGenerator < Rails::Generators::NamedBase # :nodoc:
|
29
|
+
|
30
|
+
source_root File.expand_path('../templates', __FILE__)
|
31
|
+
|
32
|
+
class_option :tabs, type: :boolean, default: false, description: "Create tabbed form"
|
33
|
+
class_option :extra, type: :boolean, default: false, description: "Add some extra commented code to the form"
|
34
|
+
|
35
|
+
def self.banner #:nodoc:
|
36
|
+
<<-BANNER.chomp
|
37
|
+
rails g agile_rails:new_form MODEL [options]
|
38
|
+
|
39
|
+
Generates Agile Rails form for specified Rails model
|
40
|
+
|
41
|
+
- options: --tabs will create form entry fields with tabs (default: --no-tabs)
|
42
|
+
--extra will create some extra commented code for help (default: --no-extra)
|
43
|
+
BANNER
|
44
|
+
end
|
45
|
+
|
46
|
+
###########################################################################
|
47
|
+
# Will create output and save it to form filename.
|
48
|
+
###########################################################################
|
49
|
+
def create_form_file
|
50
|
+
@file_name = file_name.underscore
|
51
|
+
@tabs = options[:tabs]
|
52
|
+
pp options
|
53
|
+
@extra = options[:extra]
|
54
|
+
begin
|
55
|
+
@model = @file_name.classify.constantize
|
56
|
+
rescue Exception => e
|
57
|
+
pp ([e.message] + e.backtrace).join($/)
|
58
|
+
@model = nil
|
59
|
+
end
|
60
|
+
return (pp "Error loading #{file_name.classify} model! Aborting.") if @model.nil?
|
61
|
+
|
62
|
+
form = top_level_options +
|
63
|
+
index_options +
|
64
|
+
data_set_options +
|
65
|
+
form_top_options +
|
66
|
+
form_fields_options +
|
67
|
+
localize_options
|
68
|
+
create_file "app/forms/#{@file_name}.yml", form
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
###########################################################################
|
73
|
+
#
|
74
|
+
###########################################################################
|
75
|
+
def top_level_options
|
76
|
+
extra = <<EOT
|
77
|
+
#title: Alternative title
|
78
|
+
#extend: extend
|
79
|
+
#controls: controls_file
|
80
|
+
#readonly: true
|
81
|
+
#permissions:
|
82
|
+
# can_view: role_name
|
83
|
+
EOT
|
84
|
+
|
85
|
+
<<EOT
|
86
|
+
# Form for #{file_name}
|
87
|
+
table: #{file_name}
|
88
|
+
#{extra if @extra}
|
89
|
+
EOT
|
90
|
+
end
|
91
|
+
|
92
|
+
###########################################################################
|
93
|
+
#
|
94
|
+
###########################################################################
|
95
|
+
def index_options
|
96
|
+
extra = <<EOT
|
97
|
+
|
98
|
+
# actions:
|
99
|
+
# 10:
|
100
|
+
# type: link
|
101
|
+
# controller: controller_name
|
102
|
+
# action: action_name
|
103
|
+
# table: table_name
|
104
|
+
# form_name: form_name
|
105
|
+
EOT
|
106
|
+
|
107
|
+
<<EOT
|
108
|
+
index:
|
109
|
+
filter: some_id as text_field
|
110
|
+
actions: standard
|
111
|
+
#{extra if @extra}
|
112
|
+
EOT
|
113
|
+
end
|
114
|
+
|
115
|
+
###########################################################################
|
116
|
+
#
|
117
|
+
###########################################################################
|
118
|
+
def data_set_options
|
119
|
+
extra = <<EOT
|
120
|
+
# filter: controls_filter
|
121
|
+
# per_page: 10
|
122
|
+
|
123
|
+
# actions:
|
124
|
+
# 10:
|
125
|
+
# type: link
|
126
|
+
# controller: controller_name
|
127
|
+
# action: action_name
|
128
|
+
# table: table_name
|
129
|
+
# form_name: form_name
|
130
|
+
# target: target
|
131
|
+
# method: (get),put,post
|
132
|
+
|
133
|
+
EOT
|
134
|
+
|
135
|
+
<<EOT
|
136
|
+
data_set:
|
137
|
+
actions: standard
|
138
|
+
#{extra if @extra}
|
139
|
+
#
|
140
|
+
# Choose columns from
|
141
|
+
# #{@model.attribute_names.join(',')}
|
142
|
+
columns:
|
143
|
+
10:
|
144
|
+
name: #{@model.attribute_names[1]}
|
145
|
+
20:
|
146
|
+
name: #{@model.attribute_names[2]}
|
147
|
+
30:
|
148
|
+
name: #{@model.attribute_names[3]}
|
149
|
+
40:
|
150
|
+
name: #{@model.attribute_names[4]}
|
151
|
+
|
152
|
+
# style: 'color: red'
|
153
|
+
# width: 10%
|
154
|
+
# align: right
|
155
|
+
# format: '%d.%m.%Y'
|
156
|
+
# format: N2
|
157
|
+
# sort: n
|
158
|
+
# eval: agile_name_for_id,ar_user,name
|
159
|
+
# eval: agile_icon_for_boolean
|
160
|
+
|
161
|
+
EOT
|
162
|
+
end
|
163
|
+
|
164
|
+
###########################################################################
|
165
|
+
#
|
166
|
+
###########################################################################
|
167
|
+
def form_top_options
|
168
|
+
extra = <<EOT
|
169
|
+
|
170
|
+
# title:
|
171
|
+
# field: name
|
172
|
+
# edit: Title for edit
|
173
|
+
# show: Title for show
|
174
|
+
|
175
|
+
#
|
176
|
+
# actions:
|
177
|
+
# 1:
|
178
|
+
# type: ajax
|
179
|
+
# controller: ppk
|
180
|
+
# action: prepare_document
|
181
|
+
# method: (get),put,post
|
182
|
+
# caption: Prepare document
|
183
|
+
# 2:
|
184
|
+
# type: script
|
185
|
+
# caption: Cancle
|
186
|
+
# js: parent.reload();
|
187
|
+
# 3:
|
188
|
+
# type: submit
|
189
|
+
# caption: Send
|
190
|
+
# params:
|
191
|
+
# before-save: send_mail
|
192
|
+
# after-save: return_to parent.reload
|
193
|
+
|
194
|
+
EOT
|
195
|
+
|
196
|
+
<<EOT
|
197
|
+
form:
|
198
|
+
actions: standard
|
199
|
+
#{extra if @extra}
|
200
|
+
EOT
|
201
|
+
end
|
202
|
+
|
203
|
+
###########################################################################
|
204
|
+
#
|
205
|
+
###########################################################################
|
206
|
+
def form_field(attribute, index, offset)
|
207
|
+
field, value = attribute
|
208
|
+
helper = I18n.t("helpers.label.#{@file_name}.choices4_#{field}")
|
209
|
+
type, eval = 'select', ''
|
210
|
+
if helper.match( /Translation missing/i )
|
211
|
+
if field[-3, 3] == '_id'
|
212
|
+
eval = "choices: eval agile_choices_for('#{field[0, field.size - 3]}','description_field_name','id')\n"
|
213
|
+
else
|
214
|
+
type = if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
215
|
+
'check_box'
|
216
|
+
else
|
217
|
+
'text_field'
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
yml = ' '*offset
|
222
|
+
yml << "#{index}:\n"
|
223
|
+
offset += 2
|
224
|
+
|
225
|
+
yml << ' '*offset + "name: #{field}\n"
|
226
|
+
yml << ' '*offset + "type: #{type}\n"
|
227
|
+
yml << ' '*offset + eval if eval.size > 0
|
228
|
+
yml << ' '*offset + "size: 50\n" if type == 'text_field'
|
229
|
+
if type == 'select'
|
230
|
+
yml << ' '*offset + "html:\n"
|
231
|
+
offset += 2
|
232
|
+
yml << ' '*offset + "include_blank: true\n"
|
233
|
+
end
|
234
|
+
yml
|
235
|
+
end
|
236
|
+
|
237
|
+
###########################################################################
|
238
|
+
#
|
239
|
+
###########################################################################
|
240
|
+
def embedded_form_field(offset)
|
241
|
+
yml = ''
|
242
|
+
field_index = 10
|
243
|
+
@model.embedded_relations.keys.each do |embedded_name|
|
244
|
+
yml << ' '*offset + "#{field_index}:\n"
|
245
|
+
yml << ' '*(offset + 2) + "name: #{embedded_name}\n"
|
246
|
+
yml << ' '*(offset + 2) + "type: embedded\n"
|
247
|
+
yml << ' '*(offset + 2) + "form_name: #{embedded_name[0,embedded_name.size - 1]}\n"
|
248
|
+
yml << '#' + ' '*(offset + 2) + "html:\n"
|
249
|
+
field_index += 10
|
250
|
+
end
|
251
|
+
yml
|
252
|
+
end
|
253
|
+
|
254
|
+
###########################################################################
|
255
|
+
#
|
256
|
+
###########################################################################
|
257
|
+
def form_fields_options
|
258
|
+
extra = <<EOT
|
259
|
+
|
260
|
+
# group: 2
|
261
|
+
# line: top bottom
|
262
|
+
# readonly: yes 1 true
|
263
|
+
# default: 10
|
264
|
+
# eval: some_method, session[:], params[:],@site.name
|
265
|
+
|
266
|
+
# type: comment
|
267
|
+
# text: myapp.comment_text
|
268
|
+
# caption: false
|
269
|
+
# html:
|
270
|
+
# style: 'color: red'
|
271
|
+
# class: some_class
|
272
|
+
|
273
|
+
# type: datetime_picker
|
274
|
+
# type: date_picker
|
275
|
+
# options: 'step: 60, inline: true'
|
276
|
+
# options: 'inline: true'
|
277
|
+
|
278
|
+
# type: text_autocomplete
|
279
|
+
# search: model_name.field_name
|
280
|
+
# search: model_name..method_name
|
281
|
+
# is_id: no
|
282
|
+
|
283
|
+
# type: select
|
284
|
+
# choices:
|
285
|
+
# eval: ModelClass.method_name
|
286
|
+
# depend: field1, field2
|
287
|
+
# include_blank: true
|
288
|
+
|
289
|
+
# type: text_area
|
290
|
+
# size: 90x10
|
291
|
+
# type: check_box
|
292
|
+
|
293
|
+
# type: number_field
|
294
|
+
# size: 10
|
295
|
+
# format: N2
|
296
|
+
|
297
|
+
# type: radio_button
|
298
|
+
# choices: 'Marantz:1,Sony:2,Bose:3,Pioneer:4'
|
299
|
+
# inline: true
|
300
|
+
|
301
|
+
# type: readonly
|
302
|
+
# name: user_id
|
303
|
+
# eval: agile_name_for_id,model_name,field_name
|
304
|
+
|
305
|
+
# type: hidden_field
|
306
|
+
# type: file_field
|
307
|
+
# type: file_select
|
308
|
+
# size: 50
|
309
|
+
# html:
|
310
|
+
# type: email
|
311
|
+
# required: true
|
312
|
+
|
313
|
+
|
314
|
+
EOT
|
315
|
+
|
316
|
+
forbidden = %w[id created_by updated_by created_at updated_at]
|
317
|
+
tab_index = 1
|
318
|
+
field_index = 0
|
319
|
+
if @tabs
|
320
|
+
yml = " tabs:\n"
|
321
|
+
@model.new.attributes.each do |attribute|
|
322
|
+
next if forbidden.include?(attribute.first)
|
323
|
+
|
324
|
+
if field_index%100 == 0
|
325
|
+
yml << "\n tab#{tab_index}:\n"
|
326
|
+
field_index = 0
|
327
|
+
tab_index += 1
|
328
|
+
end
|
329
|
+
yml << form_field(attribute, field_index += 10, 6)
|
330
|
+
end
|
331
|
+
else
|
332
|
+
yml = " fields:\n"
|
333
|
+
@model.new.attributes.each do |attribute|
|
334
|
+
next if forbidden.include?(attribute.first)
|
335
|
+
|
336
|
+
yml << form_field(attribute, field_index += 10, 4)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
yml + (@extra ? extra : '')
|
340
|
+
end
|
341
|
+
|
342
|
+
###########################################################################
|
343
|
+
#
|
344
|
+
###########################################################################
|
345
|
+
def localize_options
|
346
|
+
forbidden = %w[id created_by updated_by created_at updated_at]
|
347
|
+
yml =<<EOT
|
348
|
+
|
349
|
+
#################################################################
|
350
|
+
# Localization
|
351
|
+
en:
|
352
|
+
helpers:
|
353
|
+
label:
|
354
|
+
#{file_name}:
|
355
|
+
table_title:
|
356
|
+
choices_for_:
|
357
|
+
|
358
|
+
EOT
|
359
|
+
@model.attribute_names.each do |attr_name|
|
360
|
+
next if forbidden.include?(attr_name)
|
361
|
+
|
362
|
+
yml << " #{attr_name}: \n"
|
363
|
+
end
|
364
|
+
yml
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
class ConvertToArGenerator < Rails::Generators::NamedBase
|
2
|
+
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
desc 'This generator converts mongoid model to active_record migration'
|
5
|
+
argument :model_name, :type => :string, :default => 'dc_*'
|
6
|
+
argument :migration_name, :type => :string, :default => 'initial_migration'
|
7
|
+
|
8
|
+
TYPES = {
|
9
|
+
String => :string,
|
10
|
+
Time => :datetime,
|
11
|
+
DateTime => :datetime,
|
12
|
+
Object => :integer,
|
13
|
+
Integer => :integer,
|
14
|
+
BSON::ObjectId => :integer,
|
15
|
+
Mongoid::Boolean => :boolean,
|
16
|
+
BigDecimal => [:decimal, :precision => 8, :scale => 2, :default => 0.00],
|
17
|
+
Date => :date,
|
18
|
+
Hash => :text,
|
19
|
+
Array => :text
|
20
|
+
}
|
21
|
+
|
22
|
+
###########################################################################
|
23
|
+
#
|
24
|
+
###########################################################################
|
25
|
+
def create_migration
|
26
|
+
p model_name, migration_name
|
27
|
+
|
28
|
+
code = model_name.match(/\*/) ? migrate_many(model_name) : migrate_one(model_name)
|
29
|
+
code = top(migration_name) + code + bottom
|
30
|
+
create_file "db/#{source_file_name(migration_name).underscore}.rb", code
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
###########################################################################
|
36
|
+
#
|
37
|
+
###########################################################################
|
38
|
+
def source_file_name(migration)
|
39
|
+
"#{Time.now.strftime("%Y%m%d%H%M%S")}_#{migration}"
|
40
|
+
end
|
41
|
+
|
42
|
+
###########################################################################
|
43
|
+
#
|
44
|
+
###########################################################################
|
45
|
+
def migrate_one(model_name)
|
46
|
+
mongo_model = model_name.classify.constantize
|
47
|
+
new_model_name = model_name.start_with?('dc_') ? model_name.sub('dc_', 'ar_') : model_name
|
48
|
+
code = %( create_table :#{new_model_name.pluralize} do |t|\n)
|
49
|
+
left = ' t.'
|
50
|
+
timestamps = false
|
51
|
+
# fields
|
52
|
+
document = mongo_model.new
|
53
|
+
document.attribute_names.each do |attribute_name|
|
54
|
+
next if attribute_name == '_id'
|
55
|
+
if %w[created_at updated_at].include?(attribute_name)
|
56
|
+
timestamps = true
|
57
|
+
next
|
58
|
+
end
|
59
|
+
|
60
|
+
options = mongo_model.fields[attribute_name].options
|
61
|
+
pp "Undefined type #{options[:type]} for #{mongo_model}.#{attribute_name}" unless TYPES[options[:type]]
|
62
|
+
att_name = attribute_name.sub(/^dc_/,'ar_')
|
63
|
+
code << %(#{left}#{TYPES[options[:type]]} :#{att_name})
|
64
|
+
code << %(, default: #{get_default(options[:default], options[:type])}) if options[:default]
|
65
|
+
code << "\n"
|
66
|
+
end
|
67
|
+
code << %(\n#{left}timestamps\n) if timestamps
|
68
|
+
|
69
|
+
# indexes
|
70
|
+
if document.index_specifications.any?
|
71
|
+
code << "\n"
|
72
|
+
document.index_specifications.each do |index|
|
73
|
+
code << "#{left}index "
|
74
|
+
code << (index.fields.size > 1 ? "[:#{index.fields.join(', :')}]" : ":#{index.fields.first}")
|
75
|
+
code << ", #{index.options.to_s.gsub(/\{|\}/, '')}" if index.options.size > 0
|
76
|
+
code << "\n"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# export some test data
|
81
|
+
data = []
|
82
|
+
mongo_model.all.limit(5).each do |doc|
|
83
|
+
#data << doc.as_document.inject([]) { |r, e| [e.first.sub(/^dc_/,'ar_'), e.last] }
|
84
|
+
data << doc.as_document.map { |e| [e.first.sub(/^dc_/,'ar_'), e.last] }
|
85
|
+
end
|
86
|
+
File.write("db/#{new_model_name}.json", data.to_json)
|
87
|
+
|
88
|
+
code << " end\n\n"
|
89
|
+
end
|
90
|
+
|
91
|
+
###########################################################################
|
92
|
+
#
|
93
|
+
###########################################################################
|
94
|
+
def get_default(default, type)
|
95
|
+
case type.to_s
|
96
|
+
when 'String' then "'#{default}'"
|
97
|
+
else default
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#########################################################################
|
102
|
+
# Return array of all models found in application.
|
103
|
+
#########################################################################
|
104
|
+
def all_collections
|
105
|
+
collections = []
|
106
|
+
AgileRAils.paths(:forms).each do |path|
|
107
|
+
models_dir = File.expand_path('../models', path)
|
108
|
+
Dir["#{models_dir}/*.rb"].each do |model_file|
|
109
|
+
model_file =~ /(.*)\/(.*).rb/
|
110
|
+
# check if model exists
|
111
|
+
collection = $2.camelize.constantize.new rescue nil
|
112
|
+
collections << collection.class.to_s.underscore if collection&.respond_to?(:_id)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
collections.sort
|
116
|
+
end
|
117
|
+
|
118
|
+
###########################################################################
|
119
|
+
#
|
120
|
+
###########################################################################
|
121
|
+
def migrate_many(model_name)
|
122
|
+
selector = model_name[0, model_name.index('*') - 1].downcase
|
123
|
+
p selector
|
124
|
+
|
125
|
+
list = all_collections.select { |name| name.starts_with?(selector) }
|
126
|
+
list.inject('') { |r, e| r << migrate_one(e) }
|
127
|
+
end
|
128
|
+
|
129
|
+
###########################################################################
|
130
|
+
#class #{migration_name} < ActiveRecord::Migration[7.0]
|
131
|
+
# def change
|
132
|
+
# create_table :products do |t|
|
133
|
+
# t.string :name
|
134
|
+
# t.text :description
|
135
|
+
#
|
136
|
+
# t.timestamps = true
|
137
|
+
# end
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
###########################################################################
|
141
|
+
def top(migration_name)
|
142
|
+
<<~EOT
|
143
|
+
class #{migration_name.classify} < ActiveRecord::Migration[7.0]
|
144
|
+
def change
|
145
|
+
EOT
|
146
|
+
end
|
147
|
+
|
148
|
+
###########################################################################
|
149
|
+
#
|
150
|
+
###########################################################################
|
151
|
+
def bottom
|
152
|
+
<<~EOT
|
153
|
+
end
|
154
|
+
end
|
155
|
+
EOT
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Thanks to Jimmy https://github.com/kejiro
|
2
|
+
#
|
3
|
+
# https://gist.githubusercontent.com/kejiro/484416/raw/56b8f3db8a62aac0fb0d007b1afd7e7b56b3ff07/Rakefile
|
4
|
+
#
|
5
|
+
#require 'activerecord'
|
6
|
+
#require 'yaml'
|
7
|
+
|
8
|
+
module DataCopier
|
9
|
+
@source = nil
|
10
|
+
@destination = nil
|
11
|
+
|
12
|
+
|
13
|
+
module Source
|
14
|
+
class Base < ActiveRecord::Base
|
15
|
+
self.abstract_class = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Destination
|
20
|
+
class Base < ActiveRecord::Base
|
21
|
+
self.abstract_class = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Base
|
26
|
+
@source = nil
|
27
|
+
@destination = nil
|
28
|
+
|
29
|
+
def write(text="")
|
30
|
+
puts(text)# if verbose
|
31
|
+
end
|
32
|
+
|
33
|
+
def announce(message)
|
34
|
+
text = "#{message}"
|
35
|
+
length = [0, 75 - text.length].max
|
36
|
+
write "== %s %s" % [text, "=" * length]
|
37
|
+
end
|
38
|
+
|
39
|
+
def say(message, subitem=false)
|
40
|
+
write "#{subitem ? " ->" : "--"} #{message}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def say_with_time(message)
|
44
|
+
say(message)
|
45
|
+
result = nil
|
46
|
+
time = Benchmark.measure { result = yield }
|
47
|
+
say "%.4fs" % time.real, :subitem
|
48
|
+
say("#{result} rows", :subitem) if result.is_a?(Integer)
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(configuration)
|
53
|
+
ActiveRecord::Base.configurations = configuration
|
54
|
+
|
55
|
+
@source = Source::Base.establish_connection(:source).connection
|
56
|
+
@destination = Destination::Base.establish_connection(:destination).connection
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def create_destination_tables(source = @source, destination = @destination)
|
62
|
+
return unless destination.tables.empty?
|
63
|
+
|
64
|
+
schema_definitions = StringIO.new
|
65
|
+
ActiveRecord::Base.establish_connection(:destination)
|
66
|
+
|
67
|
+
say_with_time("Dumping the schema from the source"){ActiveRecord::SchemaDumper.dump(source, schema_definitions)}
|
68
|
+
say_with_time("Loading the schema in the destination"){eval(schema_definitions.string)}
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_models(tables = @source.tables)
|
72
|
+
tables.each do |table|
|
73
|
+
class_name = table.downcase.classify
|
74
|
+
Source.module_eval <<-DECL
|
75
|
+
class #{class_name} < Source::Base
|
76
|
+
#set_table_name "#{table}"
|
77
|
+
self.table_name = "#{table}"
|
78
|
+
end
|
79
|
+
DECL
|
80
|
+
|
81
|
+
Destination.module_eval <<-DECL
|
82
|
+
class #{class_name} < Destination::Base
|
83
|
+
#set_table_name "#{table}"
|
84
|
+
self.table_name = "#{table}"
|
85
|
+
end
|
86
|
+
DECL
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def copy_data(tables = @source.tables)
|
91
|
+
skip = %w[schema_migrations ar_journals]
|
92
|
+
tables.each do |table|
|
93
|
+
next if skip.include?(table)
|
94
|
+
|
95
|
+
source_model = "DataCopier::Source::#{table.downcase.classify}".constantize
|
96
|
+
destination_model = "DataCopier::Destination::#{table.downcase.classify}".constantize
|
97
|
+
destination_model.delete_all
|
98
|
+
rows_to_copy = source_model.count
|
99
|
+
rows_copied = 0
|
100
|
+
say_with_time("Copying #{rows_to_copy} rows from #{table.downcase}"){
|
101
|
+
source_model.all.each do |row|
|
102
|
+
destination_model.create(row.attributes)
|
103
|
+
rows_copied += 1
|
104
|
+
end
|
105
|
+
rows_copied
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def run
|
112
|
+
create_destination_tables(@source, @destination)
|
113
|
+
create_models(@source.tables)
|
114
|
+
copy_data(@source.tables)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#########################################################################
|
120
|
+
namespace :agile do
|
121
|
+
namespace :db do
|
122
|
+
task :setup do
|
123
|
+
configuration_file = ENV['config'] || 'config/database.yml'
|
124
|
+
raise "Can't find the configuration file, please specify with: env config=<path to file>" unless File.exist?(configuration_file)
|
125
|
+
@configuration = YAML.load_file(configuration_file, aliases: true)
|
126
|
+
end
|
127
|
+
|
128
|
+
task :clone => :setup do
|
129
|
+
DataCopier::Base.new(@configuration).run
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#Rails.initialize!
|
2
|
+
|
3
|
+
#########################################################################
|
4
|
+
#
|
5
|
+
#########################################################################
|
6
|
+
def agile_db_export_to_yaml
|
7
|
+
h = {}
|
8
|
+
all_models = (ActiveRecord::Base.connection.tables - %w[schema_migrations sessions])
|
9
|
+
all_models.each do |model_name|
|
10
|
+
p model_name
|
11
|
+
|
12
|
+
model = model_name.classify.constantize rescue nil
|
13
|
+
next if model.nil?
|
14
|
+
next unless model.all.count > 0
|
15
|
+
|
16
|
+
p model.column_names
|
17
|
+
a = []
|
18
|
+
model.all.each do |record|
|
19
|
+
a << model.column_names.each_with_object({}) do |column, r|
|
20
|
+
r[column] = record[column] if record[column].present?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
h[model_name] = a
|
24
|
+
end
|
25
|
+
File.write('out.txt', h.to_yaml)
|
26
|
+
end
|
27
|
+
|
28
|
+
#########################################################################
|
29
|
+
namespace :agile do
|
30
|
+
namespace :db do
|
31
|
+
desc "agile:db:export, export database to text file in yaml format"
|
32
|
+
task :export => :environment do
|
33
|
+
agile_db_export_to_yaml
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|