the_jobbook_admin_data 1.3.0a

Sign up to get free protection for your applications and to get access to all the features.
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