the_jobbook_admin_data 1.3.0a

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.
Files changed (174) hide show
  1. data/.gitignore +19 -0
  2. data/CHANGELOG.rdoc +284 -0
  3. data/Gemfile +22 -0
  4. data/Gemfile.lock +121 -0
  5. data/Guardfile +14 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +37 -0
  8. data/README.rdoc +3 -0
  9. data/Rakefile +40 -0
  10. data/admin_data.gemspec +23 -0
  11. data/app/assets/images/add.png +0 -0
  12. data/app/assets/images/admin_data/.gitkeep +0 -0
  13. data/app/assets/images/no.png +0 -0
  14. data/app/assets/images/site.png +0 -0
  15. data/app/assets/images/sort_by_asc.jpg +0 -0
  16. data/app/assets/images/sort_by_desc.jpg +0 -0
  17. data/app/assets/images/sort_by_nothing.jpg +0 -0
  18. data/app/assets/javascripts/admin_data.js +18 -0
  19. data/app/assets/javascripts/admin_data/application.js +15 -0
  20. data/app/assets/javascripts/advance_search/act_on_result.js +45 -0
  21. data/app/assets/javascripts/advance_search/advance_search.js +83 -0
  22. data/app/assets/javascripts/advance_search/advance_search_structure.js +79 -0
  23. data/app/assets/javascripts/advance_search/ajaxify_advance_search.js +28 -0
  24. data/app/assets/javascripts/advance_search/build_first_row.js +8 -0
  25. data/app/assets/javascripts/advance_search/event_bindings.js +76 -0
  26. data/app/assets/javascripts/advance_search/global_ajax_setting.js +10 -0
  27. data/app/assets/javascripts/advance_search/sortby.js +14 -0
  28. data/app/assets/javascripts/advance_search/trigger_submit_on_domready.js +6 -0
  29. data/app/assets/javascripts/analytics/report.js +7 -0
  30. data/app/assets/javascripts/misc/drop_down_change.js +8 -0
  31. data/app/assets/javascripts/misc/js_util.js +58 -0
  32. data/app/assets/javascripts/misc/quick_search_input_focus.js +6 -0
  33. data/app/assets/javascripts/vendor/jquery-1.4.2.js +6240 -0
  34. data/app/assets/javascripts/vendor/jquery-ui-1.7.2.custom.min.js +298 -0
  35. data/app/assets/javascripts/vendor/jquery.ba-isjquery.js +21 -0
  36. data/app/assets/javascripts/vendor/jquery_form.js +814 -0
  37. data/app/assets/javascripts/vendor/log.js +9 -0
  38. data/app/assets/javascripts/vendor/rails.js +132 -0
  39. data/app/assets/stylesheets/admin_data.css +1141 -0
  40. data/app/assets/stylesheets/admin_data/application.css +13 -0
  41. data/app/assets/stylesheets/vendor/jquery-ui-1.7.2.custom.css +406 -0
  42. data/app/controllers/admin_data/application_controller.rb +107 -0
  43. data/app/controllers/admin_data/crud_controller.rb +100 -0
  44. data/app/controllers/admin_data/feed_controller.rb +48 -0
  45. data/app/controllers/admin_data/home_controller.rb +8 -0
  46. data/app/controllers/admin_data/migration_controller.rb +18 -0
  47. data/app/controllers/admin_data/public_controller.rb +28 -0
  48. data/app/controllers/admin_data/search_controller.rb +143 -0
  49. data/app/controllers/admin_data/table_structure_controller.rb +25 -0
  50. data/app/helpers/admin_data/application_helper.rb +320 -0
  51. data/app/views/admin_data/crud/association/_association_info.html.erb +11 -0
  52. data/app/views/admin_data/crud/association/_belongs_to_info.html.erb +7 -0
  53. data/app/views/admin_data/crud/association/_habtm_info.html.erb +7 -0
  54. data/app/views/admin_data/crud/association/_has_many_info.html.erb +7 -0
  55. data/app/views/admin_data/crud/association/_has_one_info.html.erb +6 -0
  56. data/app/views/admin_data/crud/edit.html.erb +36 -0
  57. data/app/views/admin_data/crud/misc/_form.html.erb +38 -0
  58. data/app/views/admin_data/crud/misc/_modify_record.html.erb +18 -0
  59. data/app/views/admin_data/crud/new.html.erb +25 -0
  60. data/app/views/admin_data/crud/show.html.erb +42 -0
  61. data/app/views/admin_data/feed/index.rss.builder +25 -0
  62. data/app/views/admin_data/home/index.html.erb +21 -0
  63. data/app/views/admin_data/migration/index.html.erb +18 -0
  64. data/app/views/admin_data/migration/jstest.html.erb +51 -0
  65. data/app/views/admin_data/search/advance_search.html.erb +1 -0
  66. data/app/views/admin_data/search/quick_search.html.erb +1 -0
  67. data/app/views/admin_data/search/search/_advance_search_form.html.erb +52 -0
  68. data/app/views/admin_data/search/search/_errors.html.erb +5 -0
  69. data/app/views/admin_data/search/search/_listing.html.erb +43 -0
  70. data/app/views/admin_data/search/search/_search_form.html.erb +27 -0
  71. data/app/views/admin_data/search/search/_title.html.erb +34 -0
  72. data/app/views/admin_data/shared/_breadcrum.html.erb +16 -0
  73. data/app/views/admin_data/shared/_drop_down_klasses.html.erb +4 -0
  74. data/app/views/admin_data/shared/_flash_message.html.erb +13 -0
  75. data/app/views/admin_data/shared/_header.html.erb +20 -0
  76. data/app/views/admin_data/shared/_powered_by.html.erb +6 -0
  77. data/app/views/admin_data/shared/_secondary_navigation.html.erb +26 -0
  78. data/app/views/admin_data/table_structure/index.html.erb +54 -0
  79. data/app/views/layouts/admin_data.html.erb +34 -0
  80. data/app/views/layouts/admin_data/application.html.erb +14 -0
  81. data/app/views/layouts/search.html.erb +71 -0
  82. data/config/routes.rb +32 -0
  83. data/lib/admin_data.rb +27 -0
  84. data/lib/admin_data/active_record_util.rb +102 -0
  85. data/lib/admin_data/analytics.rb +176 -0
  86. data/lib/admin_data/authenticator.rb +15 -0
  87. data/lib/admin_data/config.rb +38 -0
  88. data/lib/admin_data/configuration.rb +127 -0
  89. data/lib/admin_data/date_util.rb +58 -0
  90. data/lib/admin_data/engine.rb +17 -0
  91. data/lib/admin_data/model_finder.rb +15 -0
  92. data/lib/admin_data/rails_version_check.rb +8 -0
  93. data/lib/admin_data/search.rb +188 -0
  94. data/lib/admin_data/setup_config.rb +24 -0
  95. data/lib/admin_data/util.rb +102 -0
  96. data/lib/admin_data/version.rb +3 -0
  97. data/lib/tasks/admin_data_tasks.rake +4 -0
  98. data/script/rails +8 -0
  99. data/test/admin_data_test.rb +7 -0
  100. data/test/dummy/README.md +19 -0
  101. data/test/dummy/Rakefile +7 -0
  102. data/test/dummy/app/controllers/application_controller.rb +3 -0
  103. data/test/dummy/app/helpers/application_helper.rb +5 -0
  104. data/test/dummy/app/models/user.rb +3 -0
  105. data/test/dummy/app/models/user/student.rb +2 -0
  106. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  107. data/test/dummy/config.ru +4 -0
  108. data/test/dummy/config/application.rb +15 -0
  109. data/test/dummy/config/boot.rb +13 -0
  110. data/test/dummy/config/cucumber.yml +9 -0
  111. data/test/dummy/config/database.yml +25 -0
  112. data/test/dummy/config/database.yml.mysql +22 -0
  113. data/test/dummy/config/database.yml.pg +15 -0
  114. data/test/dummy/config/database.yml.sqlite3 +25 -0
  115. data/test/dummy/config/environment.rb +5 -0
  116. data/test/dummy/config/environments/development.rb +22 -0
  117. data/test/dummy/config/environments/production.rb +49 -0
  118. data/test/dummy/config/environments/test.rb +35 -0
  119. data/test/dummy/config/initializers/admin_data.rb +15 -0
  120. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  121. data/test/dummy/config/initializers/empty_spaces_to_nil.rb +10 -0
  122. data/test/dummy/config/initializers/inflections.rb +10 -0
  123. data/test/dummy/config/initializers/mime_types.rb +5 -0
  124. data/test/dummy/config/initializers/secret_token.rb +7 -0
  125. data/test/dummy/config/initializers/session_store.rb +8 -0
  126. data/test/dummy/config/locales/en.yml +5 -0
  127. data/test/dummy/config/routes.rb +9 -0
  128. data/test/dummy/db/development.sqlite3 +0 -0
  129. data/test/dummy/db/migrate/20091030202259_create_tables.rb +72 -0
  130. data/test/dummy/db/production.sqlite3 +1 -0
  131. data/test/dummy/db/schema.rb +23 -0
  132. data/test/dummy/db/seeds.rb +40 -0
  133. data/test/dummy/db/test.sqlite3 +0 -0
  134. data/test/dummy/features/advance_search/boolean.feature +74 -0
  135. data/test/dummy/features/advance_search/datetime.feature +101 -0
  136. data/test/dummy/features/advance_search/delete_all.feature +20 -0
  137. data/test/dummy/features/advance_search/destroy_all.feature +20 -0
  138. data/test/dummy/features/advance_search/integer.feature +69 -0
  139. data/test/dummy/features/advance_search/multiple_rows.feature +87 -0
  140. data/test/dummy/features/advance_search/string.feature +130 -0
  141. data/test/dummy/features/crud.feature +50 -0
  142. data/test/dummy/features/crud_show.feature +56 -0
  143. data/test/dummy/features/feed.feature +13 -0
  144. data/test/dummy/features/home.feature +42 -0
  145. data/test/dummy/features/migration.feature +7 -0
  146. data/test/dummy/features/quick_search.feature +113 -0
  147. data/test/dummy/features/step_definitions/advance_search_steps.rb +13 -0
  148. data/test/dummy/features/step_definitions/app_steps.rb +36 -0
  149. data/test/dummy/features/step_definitions/async.rb +18 -0
  150. data/test/dummy/features/step_definitions/configuration_steps.rb +61 -0
  151. data/test/dummy/features/step_definitions/crud_show_steps.rb +37 -0
  152. data/test/dummy/features/step_definitions/feed_steps.rb +24 -0
  153. data/test/dummy/features/step_definitions/quick_search_steps.rb +68 -0
  154. data/test/dummy/features/step_definitions/util.rb +90 -0
  155. data/test/dummy/features/step_definitions/web_steps.rb +219 -0
  156. data/test/dummy/features/support/env.rb +66 -0
  157. data/test/dummy/features/support/hooks.rb +9 -0
  158. data/test/dummy/features/support/paths.rb +33 -0
  159. data/test/dummy/features/table_structure.feature +18 -0
  160. data/test/dummy/lib/tasks/.gitkeep +0 -0
  161. data/test/dummy/lib/tasks/cucumber.rake +53 -0
  162. data/test/dummy/lib/tasks/dbs.rake +30 -0
  163. data/test/dummy/lib/tasks/sample_cars.rake +18 -0
  164. data/test/dummy/public/.gitkeep +0 -0
  165. data/test/dummy/script/cucumber +10 -0
  166. data/test/dummy/script/rails +6 -0
  167. data/test/dummy/test/factories.rb +30 -0
  168. data/test/dummy/test/test_helper.rb +7 -0
  169. data/test/integration/navigation_test.rb +10 -0
  170. data/test/test_helper.rb +15 -0
  171. data/test/unit/admin_data/model_finder_test.rb +16 -0
  172. data/test/unit/car_test.rb +96 -0
  173. data/test/unit/user_phone_test.rb +19 -0
  174. metadata +253 -0
@@ -0,0 +1,100 @@
1
+ module AdminData
2
+
3
+ class CrudController < ApplicationController
4
+
5
+ before_filter :get_class_from_params, :only => [:show, :destroy, :del, :edit, :new, :update, :create]
6
+
7
+ before_filter :get_model_and_verify_it, :only => [:destroy, :del, :edit, :update, :show]
8
+
9
+ before_filter :ensure_is_allowed_to_update, :only => [:destroy, :del, :edit, :update, :create]
10
+
11
+ def show
12
+ @page_title = "#{@klass.name.underscore}:#{@model.id}"
13
+ respond_to {|format| format.html}
14
+ end
15
+
16
+ def destroy
17
+ @klass.send(:destroy, params[:id])
18
+ redirect_to admin_data_search_path(:klass => @klass.name.underscore)
19
+ end
20
+
21
+ def del
22
+ @klass.send(:delete, params[:id])
23
+ flash[:success] = 'Record was deleted'
24
+ redirect_to admin_data_search_path(:klass => @klass.name.underscore)
25
+ end
26
+
27
+ def edit
28
+ @page_title = "edit #{@klass.name.underscore}:#{@model.id}"
29
+ @columns = columns_list
30
+ respond_to {|format| format.html}
31
+ end
32
+
33
+ def new
34
+ @page_title = "new #{@klass.name.underscore}"
35
+ @model = @klass.send(:new)
36
+ @columns = columns_list
37
+ respond_to {|format| format.html}
38
+ end
39
+
40
+ def update
41
+ model_attrs = params[@klass.name.underscore]
42
+ @columns = columns_list
43
+
44
+ respond_to do |format|
45
+ if @model.update_attributes(model_attrs)
46
+ format.html do
47
+ flash[:success] = "Record was updated"
48
+ redirect_to admin_data_path(:id => @model.id, :klass => @klass.name.underscore)
49
+ end
50
+ format.js { render :json => {:success => true}}
51
+ else
52
+ format.html { render :action => 'edit' }
53
+ format.js { render :json => {:error => @model.errors.full_messages.join } }
54
+ end
55
+ end
56
+ end
57
+
58
+ def create
59
+ model_attrs = params[@klass.name.underscore]
60
+ @model = @klass.create(model_attrs)
61
+ @columns = columns_list
62
+
63
+ respond_to do |format|
64
+ if @model.errors.any?
65
+ format.html { render :action => 'new' }
66
+ format.js { render :json => {:error => @model.errors.full_messages.join() }}
67
+ else
68
+ format.html do
69
+ flash[:success] = "Record was created"
70
+ redirect_to admin_data_path(:id => @model.id, :klass => @klass.name.underscore)
71
+ end
72
+ format.js { render :json => {} }
73
+ end
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def get_model_and_verify_it
80
+ primary_key = @klass.primary_key.intern
81
+ conditional_id = params[:id] =~ /^(\d+)-.*/ ? params[:id].to_i : params[:id]
82
+ condition = {primary_key => conditional_id}
83
+
84
+ _proc = AdminData.config.find_conditions[@klass.name]
85
+ if _proc && (find_conditions = _proc.call(params)) && find_conditions.has_key?(:conditions)
86
+ condition = find_conditions.fetch(:conditions)
87
+ end
88
+
89
+ unless @model = @klass.find(:first, :conditions => condition)
90
+ render :text => "#{@klass.name} not found: #{params[:id]}"
91
+ return
92
+ end
93
+ end
94
+
95
+ def columns_list
96
+ params[:attr].blank? ? @klass.columns : @klass.columns.find_all {|col| params[:attr] == col.name}
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,48 @@
1
+ module AdminData
2
+
3
+ class FeedController < ApplicationController
4
+
5
+ before_filter :ensure_is_allowed_to_view_feed
6
+
7
+ def index
8
+ if params[:klasss].blank?
9
+ render :text => "Usage: http://localhost:3000/admin_data/feed/user replace user with your model name"
10
+ return
11
+ end
12
+
13
+ begin
14
+ @klass = Util.camelize_constantize(params[:klasss])
15
+ @title = "Feeds from admin_data #{@klass.name}"
16
+ @description = "feeds from AdminData #{@klass.name}"
17
+ @records = @klass.find(:all, :order => "#{@klass.primary_key} desc", :limit => 100)
18
+ rescue NameError
19
+ render :text => "No constant was found with name #{params[:klasss]}"
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def ensure_is_allowed_to_view_feed
26
+ render :text => 'not authorized' unless is_allowed_to_view_feed?(self)
27
+ end
28
+
29
+ def is_allowed_to_view_feed?(controller)
30
+ return true if Rails.env.development?
31
+
32
+ if AdminData.config.feed_authentication_user_id.blank?
33
+ Rails.logger.info 'No user id has been supplied for feed'
34
+ return false
35
+ elsif AdminData.config.feed_authentication_password.blank?
36
+ Rails.logger.info 'No password has been supplied for feed'
37
+ return false
38
+ end
39
+
40
+ userid = AdminData.config.feed_authentication_user_id
41
+ password = AdminData.config.feed_authentication_password
42
+ authenticator = AdminData::Authenticator.new(userid, password)
43
+ authenticator.verify(controller)
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,8 @@
1
+ module AdminData
2
+ class HomeController < ApplicationController
3
+ respond_to :html
4
+
5
+ def index
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ module AdminData
2
+ class MigrationController < ApplicationController
3
+
4
+ before_filter :ensure_is_allowed_to_view
5
+
6
+ def index
7
+ @page_title = 'migration information'
8
+ @data = ActiveRecord::Base.connection.select_all('select * from schema_migrations')
9
+ respond_to {|format| format.html}
10
+ end
11
+
12
+ def jstest
13
+ @page_title = 'jstest'
14
+ respond_to {|format| format.html { render :layout => false}}
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ module AdminData
2
+ class PublicController < ApplicationController
3
+
4
+ def serve
5
+ path = File.join(AdminData::LIBPATH, '..', 'app', 'assets', params[:file])
6
+
7
+ unless File.expand_path(path) =~ /admin_data/
8
+ render :nothing => true, :status => 404 and return
9
+ end
10
+
11
+ case params[:format].to_s.downcase
12
+ when 'css'
13
+ content_type = "text/css"
14
+ when 'js'
15
+ content_type = "text/javascript"
16
+ when 'png'
17
+ content_type = "image/png"
18
+ when 'jpg'
19
+ content_type = "image/jpg"
20
+ else
21
+ render :nothing => true, :status => 404 and return
22
+ end
23
+
24
+ render({:text => File.read("#{path}.#{params[:format]}"), :cache => true, :content_type => content_type})
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,143 @@
1
+ class SearchAction
2
+ attr_accessor :relation, :success_message
3
+
4
+ def initialize(relation)
5
+ @relation = relation
6
+ end
7
+
8
+ def delete
9
+ count = relation.count
10
+ relation.delete_all
11
+ self.success_message = "#{count} #{AdminData::Util.pluralize(count, 'record')} deleted"
12
+ end
13
+
14
+ def destroy
15
+ count = relation.count
16
+ relation.find_in_batches do |group|
17
+ group.each {|record| record.destroy }
18
+ end
19
+ self.success_message = "#{count} #{AdminData::Util.pluralize(count, 'record')} destroyed"
20
+ end
21
+ end
22
+
23
+ module AdminData
24
+ class SearchController < ApplicationController
25
+
26
+ layout 'search'
27
+
28
+ include AdminData::Search
29
+
30
+ before_filter :get_class_from_params
31
+ before_filter :ensure_valid_children_klass, :only => [:quick_search]
32
+ before_filter :ensure_is_authorized_for_update_opration, :only => [:advance_search]
33
+ before_filter :set_column_type_info, :only => [:advance_search]
34
+ before_filter :handle_sorting
35
+
36
+
37
+ def quick_search
38
+ @page_title = "Search #{@klass.name.underscore}"
39
+ order = default_order
40
+
41
+ if params[:base]
42
+ klass = Util.camelize_constantize(params[:base])
43
+ model = klass.find(params[:model_id])
44
+ has_many_proxy = model.send(params[:children].intern)
45
+ @total_num_of_children = has_many_proxy.send(:count)
46
+ h = { :page => params[:page], :per_page => per_page, :order => order }
47
+ @records = has_many_proxy.send(:paginate, h)
48
+ else
49
+ params[:query] = params[:query].strip unless params[:query].blank?
50
+ cond = build_quick_search_condition(@klass, params[:query])
51
+ h = { :page => params[:page], :per_page => per_page, :order => order, :conditions => cond }
52
+ @records = @klass.unscoped.paginate(h)
53
+ end
54
+ respond_to {|format| format.html}
55
+ end
56
+
57
+
58
+ def advance_search
59
+ @page_title = "Advance search #{@klass.name.underscore}"
60
+ hash = build_advance_search_condition(@klass, params[:adv_search])
61
+ relation = hash[:cond]
62
+ errors = hash[:errors]
63
+ order = default_order
64
+
65
+ respond_to do |format|
66
+ format.html { render }
67
+ format.js {
68
+
69
+ unless hash[:errors].blank?
70
+ file = File.join(AdminData::LIBPATH, '..', 'app','views', 'admin_data', 'search', 'search', '_errors.html.erb')
71
+ render :file => file, :locals => {:errors => errors}
72
+ return
73
+ end
74
+
75
+ search_action = SearchAction.new(relation)
76
+
77
+ case params[:admin_data_advance_search_action_type]
78
+ when 'destroy'
79
+ search_action.destroy
80
+ when 'delete'
81
+ search_action.delete
82
+ else
83
+ @records = relation.order(order).paginate(:page => params[:page], :per_page => per_page)
84
+ end
85
+
86
+ if search_action.success_message
87
+ render :json => {:success => search_action.success_message }
88
+ else
89
+ file = "/admin_data/search/search/listing.html.erb"
90
+ render :partial => file, :locals => {:klass => @klass}, :layout => false
91
+ end
92
+ }
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def ensure_valid_children_klass
99
+ if params[:base]
100
+ begin
101
+ model_klass = Util.camelize_constantize(params[:base])
102
+ rescue NameError => e #incase params[:base] is junk value
103
+ render :text => "#{params[:base]} is an invalid value", :status => :not_found
104
+ return
105
+ end
106
+
107
+ ar_util = ActiveRecordUtil.new(model_klass)
108
+ if ar_util.declared_has_many_association_names.include?(params[:children]) || ar_util.declared_habtm_association_names.include?(params[:children])
109
+ #proceed
110
+ else
111
+ render :text => "#{params[:children]} is not a valid has_many association", :status => :not_found
112
+ return
113
+ end
114
+ end
115
+ end
116
+
117
+ def ensure_is_authorized_for_update_opration
118
+ if %w(destroy delete).include? params[:admin_data_advance_search_action_type]
119
+ render :text => 'not authorized' unless is_allowed_to_update?
120
+ end
121
+ end
122
+
123
+ def default_order
124
+ params[:sortby] || "#{@klass.send(:table_name)}.#{@klass.send(:primary_key)} desc"
125
+ end
126
+
127
+ def set_column_type_info
128
+ column_type_info = @klass.columns.collect { |column|
129
+ #JSLint complains if a hash has key named boolean. So I am changing the key to booleant
130
+ column_type = (column.type.to_s == 'boolean') ? 'booleant' : column.type.to_s
131
+ %Q{ "#{column.name}":"#{column_type}" }
132
+ }.join(',')
133
+ @column_type_info = "{#{column_type_info}}"
134
+ end
135
+
136
+ def handle_sorting
137
+ sort_order = params[:sortby] || 'id desc'
138
+ @sort_by_column_name, @sort_order = sort_order.split
139
+ @sort_css = @sort_order == 'asc' ? 'sort_by_asc' : 'sort_by_desc'
140
+ end
141
+
142
+ end
143
+ end
@@ -0,0 +1,25 @@
1
+ module AdminData
2
+ class TableStructureController < ApplicationController
3
+
4
+ before_filter :get_class_from_params
5
+
6
+ def index
7
+ @page_title = 'table_structure'
8
+ @indexes = []
9
+ if (indexes = ActiveRecord::Base.connection.indexes(@klass.table_name)).any?
10
+ add_index_statements = indexes.map do |index|
11
+ statment_parts = [ ('add_index ' + index.table.inspect) ]
12
+ statment_parts << index.columns.inspect
13
+ statment_parts << (':name => ' + index.name.inspect)
14
+ statment_parts << ':unique => true' if index.unique
15
+
16
+ ' ' + statment_parts.join(', ')
17
+ end
18
+ add_index_statements.sort.each { |index| @indexes << index }
19
+ end
20
+ respond_to {|format| format.html}
21
+ end
22
+
23
+ end
24
+ end
25
+
@@ -0,0 +1,320 @@
1
+ module AdminData
2
+ module ApplicationHelper
3
+
4
+ def get_sort_order(column)
5
+ if column == @sort_by_column_name && @sort_order == 'desc'
6
+ "#{column} asc"
7
+ else
8
+ "#{column} desc"
9
+ end
10
+ end
11
+
12
+ def get_sort_title_with_url(column, klass)
13
+ order = get_sort_order(column)
14
+ link_to column_title(klass, column), search_path(:klass => klass, :query => params[:query], :sortby => order)
15
+ end
16
+
17
+ def get_sort_class(column)
18
+ sort_class = 'sortable'
19
+ if column == @sort_by_column_name
20
+ sort_class << ' ' + @sort_css
21
+ end
22
+ sort_class
23
+ end
24
+
25
+ def parent_layout(layout)
26
+ content_for(:layout, self.output_buffer)
27
+ self.output_buffer = render(:file => "layouts/#{layout}")
28
+ end
29
+
30
+ def column_title(klass, column)
31
+ AdminData.config.column_headers[klass.name].try(:fetch,column.intern, nil) || column
32
+ end
33
+
34
+ # AdminData.config.columns_order might not list all the columns of a given table. However
35
+ # the listed columns should be at the front in the order mentioned. Primary key will also
36
+ # be the first column. Consumer might define a new column name that is not listed a column.
37
+ #
38
+ def columns_order(klass)
39
+ columns_symbol = klass.columns.map {|e| e.name.intern}
40
+
41
+ # created_at and updated_at should be at the very end by default
42
+ if columns_symbol.include? :created_at
43
+ columns_symbol = (columns_symbol - [:created_at]) + [:created_at]
44
+ end
45
+ if columns_symbol.include? :updated_at
46
+ columns_symbol = (columns_symbol - [:updated_at]) + [:updated_at]
47
+ end
48
+
49
+ if requested_order = AdminData.config.columns_order[klass.name]
50
+ primary_key = klass.send(:primary_key).intern
51
+ order = [primary_key] + requested_order
52
+ order.uniq!
53
+ # add the columns not covered by user at the end of the list
54
+ sorted_columns = order + (columns_symbol - order)
55
+ sorted_columns.map(&:to_s)
56
+ else
57
+ columns_symbol.map(&:to_s)
58
+ end
59
+ end
60
+
61
+ def total_records_info(klass)
62
+ '(Total ' + pluralize(klass.count, 'record') + ' )'
63
+ end
64
+
65
+ def search_result_title(total_num_of_children, records)
66
+ output = []
67
+ if params[:base]
68
+ label = params[:base].camelize + ' ID ' + params[:model_id]
69
+ output << link_to(label, admin_data_path(:klass => params[:base], :id => params[:model_id]))
70
+ output << 'has'
71
+ output << pluralize(total_num_of_children, params[:klass])
72
+
73
+ elsif !params[:query].blank? || params[:adv_search]
74
+ output << 'Search result:'
75
+ output << pluralize(records.total_entries, 'record')
76
+ output << 'found'
77
+
78
+ else
79
+ output << 'All '
80
+ output << params[:klass].camelize
81
+ output << 'records'
82
+ end
83
+ output.join(' ').html_safe
84
+ end
85
+
86
+ def column_native(klass, column)
87
+ klass.send(:columns).select {|r| r.instance_variable_get('@name') == column}.first || column
88
+ end
89
+
90
+ def has_one(model, klass)
91
+ tmp = ActiveRecordUtil.new(klass).declared_has_one_association_names
92
+ tmp.inject('') do |output, ho|
93
+ begin
94
+ label = ho
95
+ if model.send(ho)
96
+ output << link_to(label, admin_data_path(:klass => ho.underscore, :id => model.send(ho)))
97
+ else
98
+ output << label
99
+ end
100
+ rescue => e
101
+ Rails.logger.debug Util.exception_info(e)
102
+ end
103
+ output
104
+ end
105
+ end
106
+
107
+ def has_many_data(model, klass)
108
+ array = ActiveRecordUtil.new(klass).declared_has_many_association_names.map do |m|
109
+ begin
110
+ count = model.send(m.intern).count
111
+ label = m.to_s + '(' + count.to_s + ')'
112
+ output = label
113
+ if count > 0
114
+ has_many_klass_name = ActiveRecordUtil.new(model.class).klass_for_association_type_and_name(:has_many, m).name.underscore
115
+ output = link_to(label, search_path( :klass => has_many_klass_name,
116
+ :children => m,
117
+ :base => klass.name.underscore,
118
+ :model_id => model.id))
119
+ end
120
+ rescue => e
121
+ Rails.logger.debug Util.exception_info(e)
122
+ end
123
+ output
124
+ end
125
+ array.join(', ')
126
+ end
127
+
128
+ def belongs_to_data(model, klass)
129
+ ActiveRecordUtil.new(klass).declared_belongs_to_association_names.map do |assoc_name|
130
+ begin
131
+ output = assoc_name
132
+ if belongs_to_record = model.send(assoc_name)
133
+ output = link_to(assoc_name, admin_data_path(:klass => belongs_to_record.class.name.underscore, :id => belongs_to_record.id))
134
+ end
135
+ rescue => e
136
+ Rails.logger.info Util.exception_info(e)
137
+ end
138
+ output
139
+ end.join(', ')
140
+ end
141
+
142
+ def habtm_data(model, klass)
143
+ ActiveRecordUtil.new(klass).declared_habtm_association_names.map do |assoc_name|
144
+ begin
145
+ count = model.send(assoc_name.intern).count
146
+ label = assoc_name + '(' + count.to_s + ')'
147
+ output = label
148
+
149
+ if count > 0 then
150
+ has_many_klass_name = ActiveRecordUtil.new(model.class).klass_for_association_type_and_name(:has_and_belongs_to_many, assoc_name).name.underscore
151
+ output = link_to(label, search_path( :klass => has_many_klass_name,
152
+ :children => assoc_name,
153
+ :base => klass.name.underscore,
154
+ :model_id => model.id))
155
+ end
156
+ rescue => e
157
+ Rails.logger.info Util.exception_info(e)
158
+ end
159
+ output
160
+ end.join(', ')
161
+ end
162
+
163
+ def breadcrum(&block)
164
+ render(:partial => '/admin_data/shared/breadcrum', :locals => {:data => capture(&block)})
165
+ end
166
+
167
+ def form_field(klass, model, col, f)
168
+ html = []
169
+ column_value = model.send(col.name)
170
+
171
+ if klass.serialized_attributes.has_key?(col.name)
172
+ return Util.get_serialized_value(html,column_value)
173
+ end
174
+
175
+ if col.primary
176
+ html << model.new_record? ? '(auto)' : model.id
177
+ elsif get_reflection_for_column(klass, col) && AdminData.config.display_assoc?( klass.name )
178
+ form_field_for_association_records(klass, col, f, html)
179
+ else
180
+ handle_column_type(col, html, model, column_value, f)
181
+ end
182
+ end
183
+
184
+
185
+ def form_field_for_association_records(klass, col, f, html)
186
+ begin
187
+ reflection = get_reflection_for_column(klass, col)
188
+
189
+ # in some edge cases following code throws exception. investigating ..
190
+ options = reflection.options
191
+ if options.keys.include?(:polymorphic) && options.fetch(:polymorphic)
192
+ build_text_field(html, f, col)
193
+ else
194
+ ref_klass = reflection.klass
195
+ association_name = ref_klass.columns.map(&:name).include?('name') ? :name : ref_klass.primary_key
196
+ all_for_dropdown = ref_klass.all(:order => "#{association_name} asc")
197
+ html << f.collection_select(col.name, all_for_dropdown, :id, association_name, :include_blank => true)
198
+ end
199
+ html.join
200
+ rescue Exception => e
201
+ Rails.logger.info Util.exception_info(e)
202
+ 'could not retrieve' # returning nil
203
+ end
204
+ end
205
+
206
+ def form_field_for_habtm_records(klass, model, f, html)
207
+ begin
208
+ html = []
209
+ ActiveRecordUtil.new(klass).delcared_habtm_association_names.each do |k|
210
+ assoc_klass = Util.get_class_name_for_habtm_association(model, k)
211
+
212
+ html << "<div class='col_box'>"
213
+ html << " <span class='col_name'>#{assoc_klass.table_name}</span>"
214
+ html << " <span class='col_type'>[integer]</span>"
215
+ html << "</div>"
216
+
217
+ order_by = assoc_klass.columns.map(&:name).include?('name') ? :name : assoc_klass.primary_key
218
+ all = assoc_klass.all(:order => order_by)
219
+ selected = model.send(assoc_klass.table_name).map{|e| e.id}
220
+ html << f.collection_select(assoc_klass.table_name, all, :id, order_by,
221
+ {:include_blank => false, :selected => selected},
222
+ {:multiple => true, :size => (all.count > 10 ? 8 : 4)})
223
+ end
224
+ html.join
225
+ rescue Exception => e
226
+ Rails.logger.info Util.exception_info(e)
227
+ 'could not retrieve' # returning nil
228
+ end
229
+ end
230
+
231
+ def handle_column_type(col, html, model, column_value, f)
232
+ case col.type
233
+ when :text
234
+ html << f.text_area(col.name, :rows => 6, :cols => 70)
235
+
236
+ when :datetime
237
+ if ['created_at', 'updated_at'].include?(col.name)
238
+ html << '(auto)'
239
+ else
240
+ value = params[:action] == 'new' ? Time.now : column_value
241
+ year_value = value.year if value
242
+ datetime_selects = f.datetime_select(col.name, :include_blank => true)
243
+ html << datetime_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
244
+ end
245
+
246
+ when :date
247
+ value = params[:action] == 'new' ? Time.now : column_value
248
+ year_value = value.year if value
249
+ date_selects = f.date_select(col.name, :discard_year => true, :include_blank => true)
250
+ html << date_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
251
+
252
+ when :time
253
+ # time_select method of rails is buggy and is causing problem
254
+ # 1 error(s) on assignment of multiparameter attributes
255
+ #
256
+ # will try again this method with Rails 3
257
+ #html << f.time_select(col.name, :include_blank => true, :include_seconds => true)
258
+
259
+ when :boolean
260
+ html << f.select(col.name, [['True', true], ['False', false]], :include_blank => true)
261
+
262
+ else
263
+ build_text_field(html, f, col)
264
+ end
265
+ html.join
266
+ end
267
+
268
+
269
+ def build_text_field(html, f, col)
270
+ options = {:class => 'nice-field'}
271
+ if AdminData.config.ignore_column_limit
272
+ options[:size] = 60
273
+ options[:maxlength] = 255
274
+ else
275
+ options[:size] = (col && col.limit && col.limit < 60) ? col.limit : 60
276
+ options[:maxlength] = col.limit if col.limit
277
+ end
278
+ html << f.text_field(col.name, options)
279
+ html.join
280
+ end
281
+
282
+ # uses truncate method
283
+ # options supports :limit which is applied if the column type is string or text.
284
+ # calls the inspect method to convert to a string if the column is serialized.
285
+ # TODO rspec test limit option
286
+ def get_value_for_column(column, model, options = {})
287
+ options.reverse_merge!(:limit => 400)
288
+
289
+ value = Util.custom_value_for_column(column, model)
290
+
291
+ if column.is_a?(String)
292
+ value
293
+ elsif column.type == :datetime
294
+ value.strftime('%d-%B-%Y %H:%M:%S %p') unless value.blank?
295
+ elsif column.type == :string || column.type == :text
296
+ value = value.inspect if model.class.serialized_attributes.keys.include?(column.name)
297
+ return value if options[:limit].blank?
298
+ begin
299
+ truncate(value,:length => options[:limit])
300
+ rescue # truncate method failed
301
+ '<actual data is not being shown because truncate method failed.>'
302
+ end
303
+ else
304
+ value.to_s
305
+ end
306
+ end
307
+
308
+ def get_reflection_for_column(klass, col)
309
+ klass.reflections.values.detect { |reflection| reflection.foreign_key.to_sym == col.name.to_sym }
310
+ end
311
+
312
+ def record_id(record)
313
+ if record.respond_to?(:primary_key)
314
+ record.send(:primary_key)
315
+ else
316
+ record.id
317
+ end
318
+ end
319
+ end
320
+ end