admin_data 1.0.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.
- data/History.txt +221 -0
- data/README.textile +21 -0
- data/Rakefile +46 -0
- data/app/controllers/admin_data/base_controller.rb +114 -0
- data/app/controllers/admin_data/diagnostic_controller.rb +28 -0
- data/app/controllers/admin_data/feed_controller.rb +17 -0
- data/app/controllers/admin_data/main_controller.rb +132 -0
- data/app/controllers/admin_data/migration_controller.rb +19 -0
- data/app/controllers/admin_data/search_controller.rb +125 -0
- data/app/controllers/admin_data/validate_model_controller.rb +106 -0
- data/app/views/admin_data/diagnostic/index.html.erb +17 -0
- data/app/views/admin_data/diagnostic/missing_index.html.erb +26 -0
- data/app/views/admin_data/feed/index.rss.builder +24 -0
- data/app/views/admin_data/main/all_models.html.erb +22 -0
- data/app/views/admin_data/main/association/_association_info.html.erb +10 -0
- data/app/views/admin_data/main/association/_belongs_to_info.html.erb +7 -0
- data/app/views/admin_data/main/association/_has_many_info.html.erb +7 -0
- data/app/views/admin_data/main/association/_has_one_info.html.erb +6 -0
- data/app/views/admin_data/main/edit.html.erb +38 -0
- data/app/views/admin_data/main/misc/_form.html.erb +25 -0
- data/app/views/admin_data/main/misc/_modify_record.html.erb +22 -0
- data/app/views/admin_data/main/new.html.erb +23 -0
- data/app/views/admin_data/main/show.html.erb +41 -0
- data/app/views/admin_data/main/table_structure.html.erb +55 -0
- data/app/views/admin_data/migration/index.html.erb +18 -0
- data/app/views/admin_data/migration/jstest.html.erb +51 -0
- data/app/views/admin_data/search/_search_base.html.erb +34 -0
- data/app/views/admin_data/search/advance_search.html.erb +3 -0
- data/app/views/admin_data/search/quick_search.html.erb +6 -0
- data/app/views/admin_data/search/search/_advance_search_form.html.erb +48 -0
- data/app/views/admin_data/search/search/_errors.html.erb +5 -0
- data/app/views/admin_data/search/search/_listing.html.erb +40 -0
- data/app/views/admin_data/search/search/_search_form.html.erb +28 -0
- data/app/views/admin_data/search/search/_sortby.html.erb +18 -0
- data/app/views/admin_data/search/search/_title.html.erb +34 -0
- data/app/views/admin_data/shared/_breadcrum.html.erb +10 -0
- data/app/views/admin_data/shared/_drop_down_klasses.html.erb +4 -0
- data/app/views/admin_data/shared/_flash_message.html.erb +13 -0
- data/app/views/admin_data/shared/_header.html.erb +23 -0
- data/app/views/admin_data/shared/_powered_by.html.erb +23 -0
- data/app/views/admin_data/shared/_secondary_navigation.html.erb +28 -0
- data/app/views/admin_data/validate_model/_bad.html.erb +1 -0
- data/app/views/admin_data/validate_model/tid.html.erb +2 -0
- data/app/views/admin_data/validate_model/validate.html.erb +67 -0
- data/app/views/layouts/admin_data.html.erb +60 -0
- data/config/routes.rb +34 -0
- data/init.rb +1 -0
- data/lib/admin_data.rb +34 -0
- data/lib/admin_data/chelper.rb +37 -0
- data/lib/admin_data/compatibility.rb +7 -0
- data/lib/admin_data/helpers.rb +222 -0
- data/lib/admin_data/railtie.rb +21 -0
- data/lib/admin_data/search.rb +186 -0
- data/lib/admin_data/settings.rb +72 -0
- data/lib/admin_data/util.rb +237 -0
- data/lib/admin_data/version.rb +3 -0
- data/lib/admin_data_date_validation.rb +79 -0
- data/lib/css/app.css +224 -0
- data/lib/css/base.css +1071 -0
- data/lib/css/header.css +65 -0
- data/lib/css/rounded.css +18 -0
- data/lib/css/themes/drastic-dark/style.css +374 -0
- data/lib/css/umbrella.css +34 -0
- data/lib/css/vendor/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png +0 -0
- data/lib/css/vendor/images/ui-bg_dots-small_65_a6a6a6_2x2.png +0 -0
- data/lib/css/vendor/images/ui-bg_flat_0_333333_40x100.png +0 -0
- data/lib/css/vendor/images/ui-bg_flat_65_ffffff_40x100.png +0 -0
- data/lib/css/vendor/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/css/vendor/images/ui-bg_glass_55_fbf8ee_1x400.png +0 -0
- data/lib/css/vendor/images/ui-bg_highlight-hard_100_eeeeee_1x100.png +0 -0
- data/lib/css/vendor/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png +0 -0
- data/lib/css/vendor/images/ui-bg_highlight-soft_15_cc0000_1x100.png +0 -0
- data/lib/css/vendor/images/ui-icons_004276_256x240.png +0 -0
- data/lib/css/vendor/images/ui-icons_cc0000_256x240.png +0 -0
- data/lib/css/vendor/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/css/vendor/jquery-ui-1.7.2.custom.css +406 -0
- data/lib/css/vendor/qunit.css +119 -0
- data/lib/js/advance_search/act_on_result.js +47 -0
- data/lib/js/advance_search/adv_search.js +46 -0
- data/lib/js/advance_search/advance_search.js +60 -0
- data/lib/js/advance_search/advance_search_structure.js +79 -0
- data/lib/js/advance_search/ajaxify_advance_search.js +28 -0
- data/lib/js/advance_search/build_first_row.js +12 -0
- data/lib/js/advance_search/event_bindings.js +87 -0
- data/lib/js/advance_search/global_ajax_setting.js +10 -0
- data/lib/js/advance_search/trigger_submit_on_domready.js +6 -0
- data/lib/js/misc/drop_down_change.js +8 -0
- data/lib/js/misc/js_util.js +42 -0
- data/lib/js/misc/quick_search_input_focus.js +6 -0
- data/lib/js/test/act_on_result.js +120 -0
- data/lib/js/test/advance_search.js +80 -0
- data/lib/js/test/ajaxify_advance_search.js +29 -0
- data/lib/js/test/build_first_row.js +10 -0
- data/lib/js/test/event_bindings.js +100 -0
- data/lib/js/validate_model/ajaxify_form.js +66 -0
- data/lib/js/validate_model/select_all.js +15 -0
- data/lib/js/vendor/jack.js +903 -0
- data/lib/js/vendor/jquery-1.4.1.js +6078 -0
- data/lib/js/vendor/jquery-ui-1.7.2.custom.min.js +298 -0
- data/lib/js/vendor/jquery.ba-isjquery.js +21 -0
- data/lib/js/vendor/jquery.form.js +814 -0
- data/lib/js/vendor/jquery.lint.js +604 -0
- data/lib/js/vendor/log.js +9 -0
- data/lib/js/vendor/qunit.js +1043 -0
- data/lib/tasks/admin_data_tasks.rake +7 -0
- data/lib/tasks/validate_models_bg.rake +23 -0
- data/test/factories/article.rb +9 -0
- data/test/factories/car.rb +4 -0
- data/test/factories/city.rb +4 -0
- data/test/factories/comment.rb +6 -0
- data/test/factories/door.rb +4 -0
- data/test/factories/engine.rb +4 -0
- data/test/functional/base_controller_test.rb +5 -0
- data/test/functional/feed_controller_test.rb +34 -0
- data/test/functional/main_controller_test.rb +421 -0
- data/test/functional/migration_controller_test.rb +30 -0
- data/test/functional/routes_test.rb +61 -0
- data/test/functional/search_controller_test.rb +814 -0
- data/test/helper/view_helper_test.rb +177 -0
- data/test/misc_tests/date_validation_test.rb +32 -0
- data/test/misc_tests/settings_test.rb +29 -0
- data/test/misc_tests/util_test.rb +83 -0
- data/test/rails_root/Gemfile +22 -0
- data/test/rails_root/Gemfile.lock +101 -0
- data/test/rails_root/Rakefile +7 -0
- data/test/rails_root/app/controllers/application_controller.rb +3 -0
- data/test/rails_root/app/helpers/application_helper.rb +2 -0
- data/test/rails_root/app/models/article.rb +25 -0
- data/test/rails_root/app/models/city.rb +15 -0
- data/test/rails_root/app/models/comment.rb +13 -0
- data/test/rails_root/app/models/tech_magazine.rb +2 -0
- data/test/rails_root/app/models/vehicle/car.rb +4 -0
- data/test/rails_root/app/models/vehicle/door.rb +3 -0
- data/test/rails_root/app/models/vehicle/engine.rb +3 -0
- data/test/rails_root/app/views/layouts/application.html.erb +14 -0
- data/test/rails_root/config.ru +4 -0
- data/test/rails_root/config/application.rb +42 -0
- data/test/rails_root/config/boot.rb +13 -0
- data/test/rails_root/config/database.yml +22 -0
- data/test/rails_root/config/environment.rb +5 -0
- data/test/rails_root/config/environments/development.rb +22 -0
- data/test/rails_root/config/environments/production.rb +49 -0
- data/test/rails_root/config/environments/test.rb +35 -0
- data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/secret_token.rb +7 -0
- data/test/rails_root/config/initializers/session_store.rb +8 -0
- data/test/rails_root/config/locales/en.yml +5 -0
- data/test/rails_root/config/routes.rb +58 -0
- data/test/rails_root/db/migrate/20090809061114_create_tables.rb +70 -0
- data/test/rails_root/db/schema.rb +74 -0
- data/test/rails_root/db/seeds.rb +7 -0
- data/test/rails_root/script/rails +6 -0
- data/test/rails_root/test/performance/browsing_test.rb +0 -0
- data/test/rails_root/test/test_helper.rb +13 -0
- data/test/support/assertions.rb +20 -0
- data/test/test_helper.rb +74 -0
- metadata +321 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module AdminData::Chelper
|
|
2
|
+
|
|
3
|
+
def per_page
|
|
4
|
+
AdminData::Config.setting[:will_paginate_per_page]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def admin_data_is_allowed_to_view?
|
|
8
|
+
return true if Rails.env.development?
|
|
9
|
+
AdminData::Config.setting[:is_allowed_to_view].call(self)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def admin_data_is_allowed_to_view_model?
|
|
13
|
+
return true if Rails.env.development?
|
|
14
|
+
AdminData::Config.setting[:is_allowed_to_view_model].call(self)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def admin_data_is_allowed_to_update?
|
|
18
|
+
return true if Rails.env.development?
|
|
19
|
+
AdminData::Config.setting[:is_allowed_to_update].call(self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def admin_data_is_allowed_to_update_model?
|
|
23
|
+
return true if Rails.env.development?
|
|
24
|
+
AdminData::Config.setting[:is_allowed_to_update_model].call(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def admin_data_invalid_record_link(klassu, id, error)
|
|
28
|
+
record = klassu.camelize.constantize.send(:find, id)
|
|
29
|
+
tmp = admin_data_on_k_path(:klass => klasss.underscore, :id => record)
|
|
30
|
+
a = []
|
|
31
|
+
a << link_to(klasss, tmp, :target => '_blank')
|
|
32
|
+
a << id
|
|
33
|
+
a << error
|
|
34
|
+
a.join(' | ')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
module AdminData::Helpers
|
|
2
|
+
|
|
3
|
+
def search_result_title(total_num_of_children, records)
|
|
4
|
+
output = []
|
|
5
|
+
if params[:base]
|
|
6
|
+
label = params[:base].camelize + ' ID ' + params[:model_id]
|
|
7
|
+
output << link_to(label, admin_data_on_k_path(:klass => params[:base], :id => params[:model_id]))
|
|
8
|
+
output << 'has'
|
|
9
|
+
output << pluralize(total_num_of_children, params[:klass])
|
|
10
|
+
|
|
11
|
+
elsif !params[:query].blank? || params[:adv_search]
|
|
12
|
+
output << 'Search result:'
|
|
13
|
+
output << pluralize(records.total_entries, 'record')
|
|
14
|
+
output << 'found'
|
|
15
|
+
|
|
16
|
+
else
|
|
17
|
+
output << 'All '
|
|
18
|
+
output << params[:klass].camelize
|
|
19
|
+
output << 'records'
|
|
20
|
+
end
|
|
21
|
+
output.join(' ').html_safe
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def admin_data_column_native(klass, column)
|
|
25
|
+
klass.send(:columns).select {|r| r.instance_variable_get('@name') == column}.first
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def admin_data_invalid_record_link(klassu, id, error)
|
|
29
|
+
record = klassu.camelize.constantize.send(:find, id)
|
|
30
|
+
tmp = admin_data_on_k_path(:klass => klassu, :id => record)
|
|
31
|
+
a = []
|
|
32
|
+
a << link_to(klassu.camelize, tmp, :target => '_blank')
|
|
33
|
+
a << id
|
|
34
|
+
a << error
|
|
35
|
+
a.join(' | ')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def admin_data_has_one(model, klass)
|
|
39
|
+
tmp = AdminData::Util.has_one_what(klass)
|
|
40
|
+
tmp.inject('') do |output, ho|
|
|
41
|
+
begin
|
|
42
|
+
label = ho
|
|
43
|
+
if model.send(ho)
|
|
44
|
+
has_one_klass_name = AdminData::Util.get_class_name_for_has_one_association(model, ho).name.underscore
|
|
45
|
+
output << link_to(label, admin_data_on_k_path(:klass => ho.underscore, :id => model.send(ho)))
|
|
46
|
+
else
|
|
47
|
+
output << label
|
|
48
|
+
end
|
|
49
|
+
rescue => e
|
|
50
|
+
Rails.logger.debug AdminData::Util.exception_info(e)
|
|
51
|
+
end
|
|
52
|
+
output
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def admin_data_has_many_data(model, klass)
|
|
57
|
+
array = AdminData::Util.has_many_what(klass).inject([]) do |output, hm|
|
|
58
|
+
begin
|
|
59
|
+
label = hm + '(' + AdminData::Util.has_many_count(model,hm).to_s + ')'
|
|
60
|
+
if AdminData::Util.has_many_count(model,hm) > 0
|
|
61
|
+
has_many_klass_name = AdminData::Util.get_class_name_for_has_many_association(model,hm).name.underscore
|
|
62
|
+
output << link_to(label, admin_data_search_path( :klass => has_many_klass_name,
|
|
63
|
+
:children => hm,
|
|
64
|
+
:base => klass.name.underscore,
|
|
65
|
+
:model_id => model.id))
|
|
66
|
+
else
|
|
67
|
+
output << label
|
|
68
|
+
end
|
|
69
|
+
rescue => e
|
|
70
|
+
Rails.logger.debug AdminData::Util.exception_info(e)
|
|
71
|
+
end
|
|
72
|
+
output
|
|
73
|
+
end
|
|
74
|
+
array.join(', ')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def admin_data_belongs_to_data(model, klass)
|
|
78
|
+
array = AdminData::Util.belongs_to_what(klass).inject([]) do |output, bt|
|
|
79
|
+
begin
|
|
80
|
+
t = AdminData::Util.get_class_name_for_belongs_to_class(model, bt)
|
|
81
|
+
klass_name = t[:polymorphic] ? 'Polymorphic' : t[:klass_name]
|
|
82
|
+
belongs_to_record = model.send(bt)
|
|
83
|
+
|
|
84
|
+
if belongs_to_record && t[:polymorphic]
|
|
85
|
+
output << link_to(belongs_to_record.class.name,
|
|
86
|
+
admin_data_on_k_path(:klass => belongs_to_record.class.name.underscore, :id => belongs_to_record))
|
|
87
|
+
elsif belongs_to_record
|
|
88
|
+
output << link_to(bt, admin_data_on_k_path(:klass => klass_name.underscore, :id => model.send(bt)))
|
|
89
|
+
else
|
|
90
|
+
output << bt
|
|
91
|
+
end
|
|
92
|
+
rescue => e
|
|
93
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
94
|
+
end
|
|
95
|
+
output
|
|
96
|
+
end
|
|
97
|
+
array.join(', ')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def admin_data_breadcrum(&block)
|
|
101
|
+
render(:partial => '/admin_data/shared/breadcrum', :locals => {:data => capture(&block)})
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def admin_data_form_field(klass, model, col, f)
|
|
105
|
+
html = []
|
|
106
|
+
column_value = model.send(col.name)
|
|
107
|
+
|
|
108
|
+
if klass.serialized_attributes.has_key?(col.name)
|
|
109
|
+
return AdminData::Util.get_serialized_value(html,column_value)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if col.primary
|
|
113
|
+
html << model.new_record? ? '(auto)' : model.id
|
|
114
|
+
|
|
115
|
+
elsif get_reflection_for_column(klass, col) && AdminData::Config.setting[:drop_down_for_associations]
|
|
116
|
+
admin_data_form_field_for_association_records(klass, col, f, html)
|
|
117
|
+
else
|
|
118
|
+
admin_data_handle_column_type(col, html, model, column_value, f)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def admin_data_form_field_for_association_records(klass, col, f, html)
|
|
124
|
+
begin
|
|
125
|
+
reflection = get_reflection_for_column(klass, col)
|
|
126
|
+
|
|
127
|
+
# in some edge cases following code throws exception. investigating ..
|
|
128
|
+
options = reflection.options
|
|
129
|
+
if options.keys.include?(:polymorphic) && options.fetch(:polymorphic)
|
|
130
|
+
build_text_field(html, f, col)
|
|
131
|
+
else
|
|
132
|
+
ref_klass = reflection.klass
|
|
133
|
+
association_name = ref_klass.columns.map(&:name).include?('name') ? :name : ref_klass.primary_key
|
|
134
|
+
all_for_dropdown = ref_klass.all(:order => "#{association_name} asc")
|
|
135
|
+
html << f.collection_select(col.name, all_for_dropdown, :id, association_name, :include_blank => true)
|
|
136
|
+
end
|
|
137
|
+
html.join
|
|
138
|
+
rescue Exception => e
|
|
139
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
140
|
+
'could not retrieve' # returning nil
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def admin_data_handle_column_type(col, html, model, column_value, f)
|
|
145
|
+
case col.type
|
|
146
|
+
when :text
|
|
147
|
+
html << f.text_area(col.name, :rows => 6, :cols => 70)
|
|
148
|
+
|
|
149
|
+
when :datetime
|
|
150
|
+
if ['created_at', 'updated_at'].include?(col.name)
|
|
151
|
+
html << model.new_record? ? '(auto)' : column_value
|
|
152
|
+
else
|
|
153
|
+
value = params[:action] == 'new' ? Time.now : column_value
|
|
154
|
+
year_value = value.year if value
|
|
155
|
+
datetime_selects = f.datetime_select(col.name, :include_blank => true)
|
|
156
|
+
html << datetime_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
when :date
|
|
160
|
+
value = params[:action] == 'new' ? Time.now : column_value
|
|
161
|
+
year_value = value.year if value
|
|
162
|
+
date_selects = f.date_select(col.name, :discard_year => true, :include_blank => true)
|
|
163
|
+
html << date_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
|
|
164
|
+
|
|
165
|
+
when :time
|
|
166
|
+
# time_select method of rails is buggy and is causing problem
|
|
167
|
+
# 1 error(s) on assignment of multiparameter attributes
|
|
168
|
+
#
|
|
169
|
+
# will try again this method with Rails 3
|
|
170
|
+
#html << f.time_select(col.name, :include_blank => true, :include_seconds => true)
|
|
171
|
+
|
|
172
|
+
when :boolean
|
|
173
|
+
html << f.select(col.name, [['True', true], ['False', false]], :include_blank => true)
|
|
174
|
+
|
|
175
|
+
else
|
|
176
|
+
build_text_field(html, f, col)
|
|
177
|
+
end
|
|
178
|
+
html.join
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def build_text_field(html, f, col)
|
|
183
|
+
options = {:class => 'nice-field'}
|
|
184
|
+
if AdminData::Config.setting[:ignore_column_limit]
|
|
185
|
+
options[:size] = 60
|
|
186
|
+
options[:maxlength] = 255
|
|
187
|
+
else
|
|
188
|
+
options[:size] = (col && col.limit && col.limit < 60) ? col.limit : 60
|
|
189
|
+
options[:maxlength] = col.limit if col.limit
|
|
190
|
+
end
|
|
191
|
+
html << f.text_field(col.name, options)
|
|
192
|
+
html.join
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# uses truncate method
|
|
196
|
+
# options supports :limit which is applied if the column type is string or text.
|
|
197
|
+
# calls the inspect method to convert to a string if the column is serialized.
|
|
198
|
+
def admin_data_get_value_for_column(column, model, options = {})
|
|
199
|
+
options.reverse_merge!(:limit => 400)
|
|
200
|
+
|
|
201
|
+
value = AdminData::Util.custom_value_for_column(column, model)
|
|
202
|
+
|
|
203
|
+
if column.type == :datetime
|
|
204
|
+
value.strftime('%d-%B-%Y %H:%M:%S %p') unless value.blank?
|
|
205
|
+
elsif column.type == :string || column.type == :text
|
|
206
|
+
value = value.inspect if model.class.serialized_attributes.keys.include?(column.name)
|
|
207
|
+
return value if options[:limit].blank?
|
|
208
|
+
begin
|
|
209
|
+
truncate(value,:length => options[:limit])
|
|
210
|
+
rescue # truncate method failed
|
|
211
|
+
'<actual data is not being shown because truncate method failed.>'
|
|
212
|
+
end
|
|
213
|
+
else
|
|
214
|
+
value
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def get_reflection_for_column(klass, col)
|
|
219
|
+
klass.reflections.values.detect { |reflection| reflection.primary_key_name.to_sym == col.name.to_sym }
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'admin_data_date_validation'
|
|
2
|
+
require 'admin_data/compatibility'
|
|
3
|
+
require 'admin_data/settings'
|
|
4
|
+
require 'admin_data/helpers'
|
|
5
|
+
require 'admin_data/util'
|
|
6
|
+
require 'admin_data/chelper'
|
|
7
|
+
|
|
8
|
+
module AdminData
|
|
9
|
+
class Engine < Rails::Engine
|
|
10
|
+
|
|
11
|
+
initializer "admin_data.setup" do
|
|
12
|
+
AdminData::Config.initialize_defaults
|
|
13
|
+
ActionView::Base.send :include, AdminData::Helpers
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
rake_tasks do
|
|
17
|
+
load 'tasks/admin_data_tasks.rake'
|
|
18
|
+
load 'tasks/validate_models_bg.rake'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module Search
|
|
2
|
+
|
|
3
|
+
class Dbbase
|
|
4
|
+
def initialize(operands, table_name, field_name, operator)
|
|
5
|
+
@operands = operands
|
|
6
|
+
@table_name = table_name
|
|
7
|
+
@field_name = field_name
|
|
8
|
+
@operator = operator
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def like_operator
|
|
12
|
+
'LIKE'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def sql_field_name
|
|
16
|
+
"#{@table_name}.#{@field_name}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def operands
|
|
20
|
+
@operands
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class PostgresqlSpecific < Dbbase
|
|
25
|
+
def like_operator
|
|
26
|
+
'ILIKE'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class OracleSpecific < Dbbase
|
|
31
|
+
def sql_field_name
|
|
32
|
+
result = super
|
|
33
|
+
%w(contains is_exactly does_not_contain).include?(@operator) ? "upper(#{result})" : result
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def operands
|
|
37
|
+
result = super
|
|
38
|
+
%w(contains is_exactly does_not_contain).include?(@operator) ? result.upcase : result
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class Term
|
|
43
|
+
|
|
44
|
+
attr_accessor :error, :table_name, :field, :operator, :operands, :dbbase
|
|
45
|
+
|
|
46
|
+
def initialize(klass, value, search_type)
|
|
47
|
+
@table_name = klass.table_name
|
|
48
|
+
compute_search_fields(value)
|
|
49
|
+
|
|
50
|
+
adapter = AdminData::Config.setting[:adapter_name].downcase
|
|
51
|
+
if adapter =~ /postgresql/
|
|
52
|
+
self.dbbase = PostgresqlSpecific.new(@operands, table_name, field, operator)
|
|
53
|
+
elsif adapter =~ /oracle/
|
|
54
|
+
self.dbbase = OracleSpecific.new(@operands, table_name, field, operator)
|
|
55
|
+
else
|
|
56
|
+
self.dbbase = Dbbase.new(@operands, table_name, field, operator)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def attribute_condition
|
|
61
|
+
return if valid? && operand_required? && operands.blank?
|
|
62
|
+
case operator
|
|
63
|
+
when 'contains'
|
|
64
|
+
["#{sql_field_name} #{like_operator} ?","%#{operands}%"]
|
|
65
|
+
|
|
66
|
+
when 'is_exactly'
|
|
67
|
+
["#{sql_field_name} = ?", operands]
|
|
68
|
+
|
|
69
|
+
when 'does_not_contain'
|
|
70
|
+
["#{sql_field_name} IS NULL OR #{sql_field_name} NOT #{like_operator} ?","%#{operands}%"]
|
|
71
|
+
|
|
72
|
+
when 'is_false'
|
|
73
|
+
["#{sql_field_name} = ?",false]
|
|
74
|
+
|
|
75
|
+
when 'is_true'
|
|
76
|
+
["#{sql_field_name} = ?",true]
|
|
77
|
+
|
|
78
|
+
when 'is_null'
|
|
79
|
+
["#{sql_field_name} IS NULL"]
|
|
80
|
+
|
|
81
|
+
when 'is_not_null'
|
|
82
|
+
["#{sql_field_name} IS NOT NULL"]
|
|
83
|
+
|
|
84
|
+
when 'is_on'
|
|
85
|
+
["#{sql_field_name} >= ? AND #{sql_field_name} < ?", values_after_cast.beginning_of_day,
|
|
86
|
+
values_after_cast.end_of_day]
|
|
87
|
+
|
|
88
|
+
when 'is_on_or_before_date'
|
|
89
|
+
["#{sql_field_name} <= ?",values_after_cast.end_of_day]
|
|
90
|
+
|
|
91
|
+
when 'is_on_or_after_date'
|
|
92
|
+
["#{sql_field_name} >= ?",values_after_cast.beginning_of_day]
|
|
93
|
+
|
|
94
|
+
when 'is_equal_to'
|
|
95
|
+
["#{sql_field_name} = ?",values_after_cast]
|
|
96
|
+
|
|
97
|
+
when 'greater_than'
|
|
98
|
+
["#{sql_field_name} > ?",values_after_cast]
|
|
99
|
+
|
|
100
|
+
when 'less_than'
|
|
101
|
+
["#{sql_field_name} < ?",values_after_cast]
|
|
102
|
+
|
|
103
|
+
else
|
|
104
|
+
# it means user did not select anything in operator. Ignore it.
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def valid?
|
|
109
|
+
@error = nil
|
|
110
|
+
@error = validate
|
|
111
|
+
@error.blank?
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
def like_operator
|
|
117
|
+
dbbase.like_operator
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def sql_field_name
|
|
121
|
+
dbbase.sql_field_name
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def operands
|
|
125
|
+
dbbase.operands
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def operand_required?
|
|
129
|
+
operator =~ /(contains|is_exactly|does_not_contain|is_on |is_on_or_before_date|is_on_or_after_date |greater_than|less_than|is_equal_to)/
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def compute_search_fields(value)
|
|
133
|
+
@field, @operator, @operands = value.values_at(:col1, :col2, :col3)
|
|
134
|
+
# field value is directly used in the sql statement. So it is important to sanitize it
|
|
135
|
+
@field = @field.gsub(/\W/,'')
|
|
136
|
+
@operands = (@operands.blank? ? @operands : @operands.strip)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def values_after_cast
|
|
140
|
+
case operator
|
|
141
|
+
when /(is_on|is_on_or_before_date|is_on_or_after_date)/
|
|
142
|
+
AdminDataDateValidation.validate(operands)
|
|
143
|
+
when /(is_equal_to|greater_than|less_than)/
|
|
144
|
+
operands.to_i
|
|
145
|
+
else
|
|
146
|
+
operands
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def validate
|
|
151
|
+
case operator
|
|
152
|
+
when /(is_on|is_on_or_before_date|is_on_or_after_date)/
|
|
153
|
+
"#{operands} is not a valid date" unless AdminDataDateValidation.validate(operands)
|
|
154
|
+
when /(is_equal_to|greater_than|less_than)/
|
|
155
|
+
unless operands.blank?
|
|
156
|
+
"#{operands} is not a valid integer" unless operands =~ /^\d+$/
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end # end of Term
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def build_quick_search_conditions( klass, search_term )
|
|
165
|
+
return nil if search_term.blank?
|
|
166
|
+
str_columns = klass.columns.select { |column| column.type.to_s =~ /(string|text)/i }
|
|
167
|
+
conditions = str_columns.collect do |column|
|
|
168
|
+
t = Term.new(klass, {:col1 => column.name, :col2 => 'contains', :col3 => search_term}, 'quick_search')
|
|
169
|
+
t.attribute_condition
|
|
170
|
+
end
|
|
171
|
+
AdminData::Util.or_merge_conditions(klass, *conditions)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def build_advance_search_conditions(klass, options)
|
|
175
|
+
values = ( options.blank? ? [] : options.values )
|
|
176
|
+
terms = values.collect {|value| Term.new(klass, value, 'advance_search') }
|
|
177
|
+
valid_terms = terms.select{ |t| t.valid? }
|
|
178
|
+
errors = (terms - valid_terms).collect { |t| t.error }
|
|
179
|
+
return {:errors => errors} if errors.any?
|
|
180
|
+
|
|
181
|
+
r = klass.unscoped
|
|
182
|
+
valid_terms.each { |t| r = r.where(t.attribute_condition) }
|
|
183
|
+
{ :cond => r }
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end
|