admin_data 1.0.22 → 1.1.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 +23 -16
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/app/controllers/admin_data/application_controller.rb +111 -0
- data/app/controllers/admin_data/crud_controller.rb +100 -0
- data/app/controllers/admin_data/feed_controller.rb +38 -16
- data/app/controllers/admin_data/home_controller.rb +11 -0
- data/app/controllers/admin_data/migration_controller.rb +12 -12
- data/app/controllers/admin_data/public_controller.rb +29 -19
- data/app/controllers/admin_data/search_controller.rb +99 -103
- data/app/controllers/admin_data/table_structure_controller.rb +25 -0
- data/app/helpers/admin_data/application_helper.rb +287 -0
- data/app/views/admin_data/crud/association/_association_info.html.erb +11 -0
- data/app/views/admin_data/crud/association/_belongs_to_info.html.erb +7 -0
- data/app/views/admin_data/{main → crud}/association/_habtm_info.html.erb +3 -3
- data/app/views/admin_data/{main → crud}/association/_has_many_info.html.erb +3 -3
- data/app/views/admin_data/crud/association/_has_one_info.html.erb +6 -0
- data/app/views/admin_data/{main → crud}/edit.html.erb +9 -9
- data/app/views/admin_data/{main → crud}/misc/_form.html.erb +6 -6
- data/app/views/admin_data/{main → crud}/misc/_modify_record.html.erb +4 -4
- data/app/views/admin_data/{main → crud}/new.html.erb +7 -7
- data/app/views/admin_data/{main → crud}/show.html.erb +10 -10
- data/app/views/admin_data/{main → home}/index.html.erb +2 -2
- data/app/views/admin_data/migration/index.html.erb +3 -3
- data/app/views/admin_data/search/_search_base.html.erb +5 -5
- data/app/views/admin_data/search/quick_search.html.erb +4 -4
- data/app/views/admin_data/search/search/_listing.html.erb +11 -9
- data/app/views/admin_data/search/search/_sortby.html.erb +4 -3
- data/app/views/admin_data/search/search/_title.html.erb +7 -7
- data/app/views/admin_data/shared/_breadcrum.html.erb +11 -5
- data/app/views/admin_data/shared/_header.html.erb +6 -6
- data/app/views/admin_data/shared/_secondary_navigation.html.erb +13 -14
- data/app/views/admin_data/{main/table_structure.html.erb → table_structure/index.html.erb} +11 -11
- data/app/views/layouts/admin_data.html.erb +15 -15
- data/config/routes.rb +3 -3
- data/lib/admin_data.rb +29 -6
- data/lib/admin_data/active_record_util.rb +38 -6
- data/lib/admin_data/configuration.rb +113 -0
- data/lib/admin_data/deprecation.rb +31 -0
- data/lib/admin_data/railtie.rb +2 -7
- data/lib/admin_data/search.rb +1 -1
- data/lib/admin_data/util.rb +74 -161
- data/lib/admin_data/version.rb +1 -1
- data/test/rails_root/app/controllers/application_controller.rb +3 -0
- data/test/rails_root/app/helpers/application_helper.rb +5 -0
- data/test/rails_root/app/models/city.rb +22 -0
- data/test/rails_root/app/models/club.rb +3 -0
- data/test/rails_root/app/models/newspaper.rb +4 -0
- data/test/rails_root/app/models/phone_number.rb +3 -0
- data/test/rails_root/app/models/user.rb +17 -0
- data/test/rails_root/app/models/website.rb +3 -0
- data/test/rails_root/config/application.rb +42 -0
- data/test/rails_root/config/boot.rb +13 -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/admin_data.rb +22 -0
- data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_root/config/initializers/empty_spaces_to_nil.rb +10 -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/routes.rb +9 -0
- data/test/rails_root/db/migrate/20091030202259_create_users.rb +55 -0
- data/test/rails_root/db/schema.rb +63 -0
- data/test/rails_root/db/seeds.rb +40 -0
- data/test/rails_root/features/step_definitions/advance_search_steps.rb +13 -0
- data/test/rails_root/features/step_definitions/app_steps.rb +40 -0
- data/test/rails_root/features/step_definitions/async.rb +18 -0
- data/test/rails_root/features/step_definitions/crud_show_steps.rb +37 -0
- data/test/rails_root/features/step_definitions/feed_steps.rb +3 -0
- data/test/rails_root/features/step_definitions/quick_search_steps.rb +65 -0
- data/test/rails_root/features/step_definitions/util.rb +86 -0
- data/test/rails_root/features/step_definitions/web_steps.rb +219 -0
- data/test/rails_root/features/support/env.rb +68 -0
- data/test/rails_root/features/support/paths.rb +33 -0
- data/test/rails_root/test/factories.rb +30 -0
- data/test/rails_root/test/performance/browsing_test.rb +9 -0
- data/test/rails_root/test/test_helper.rb +13 -0
- metadata +100 -49
- data/app/controllers/admin_data/base_controller.rb +0 -112
- data/app/controllers/admin_data/main_controller.rb +0 -141
- data/app/views/admin_data/main/association/_association_info.html.erb +0 -11
- data/app/views/admin_data/main/association/_belongs_to_info.html.erb +0 -7
- data/app/views/admin_data/main/association/_has_one_info.html.erb +0 -6
- data/lib/admin_data/chelper.rb +0 -37
- data/lib/admin_data/helpers.rb +0 -271
- data/lib/admin_data/settings.rb +0 -67
- data/lib/css/base.css +0 -1108
- data/lib/css/vendor/jquery-ui-1.7.2.custom.css +0 -406
- data/lib/js/advance_search/act_on_result.js +0 -45
- data/lib/js/advance_search/advance_search.js +0 -83
- data/lib/js/advance_search/advance_search_structure.js +0 -79
- data/lib/js/advance_search/ajaxify_advance_search.js +0 -28
- data/lib/js/advance_search/build_first_row.js +0 -8
- data/lib/js/advance_search/event_bindings.js +0 -76
- data/lib/js/advance_search/global_ajax_setting.js +0 -10
- data/lib/js/advance_search/trigger_submit_on_domready.js +0 -6
- data/lib/js/misc/drop_down_change.js +0 -8
- data/lib/js/misc/js_util.js +0 -58
- data/lib/js/misc/quick_search_input_focus.js +0 -6
- data/lib/js/test/act_on_result.js +0 -120
- data/lib/js/test/advance_search.js +0 -80
- data/lib/js/test/ajaxify_advance_search.js +0 -29
- data/lib/js/test/build_first_row.js +0 -10
- data/lib/js/test/event_bindings.js +0 -100
- data/lib/js/vendor/jack.js +0 -903
- data/lib/js/vendor/jquery-1.4.2.js +0 -6240
- data/lib/js/vendor/jquery-ui-1.7.2.custom.min.js +0 -298
- data/lib/js/vendor/jquery.ba-isjquery.js +0 -21
- data/lib/js/vendor/jquery.form.js +0 -814
- data/lib/js/vendor/log.js +0 -9
- data/lib/js/vendor/qunit.js +0 -1043
- data/lib/js/vendor/rails.js +0 -132
|
@@ -1,27 +1,37 @@
|
|
|
1
|
+
module AdminData
|
|
2
|
+
class PublicController < ApplicationController
|
|
1
3
|
|
|
2
|
-
|
|
4
|
+
def serve
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
# validate filename with a white list
|
|
7
|
+
unless self.class.admin_data_assets.include? params[:file]
|
|
8
|
+
render :nothing => true, :status => 404 and return
|
|
9
|
+
end
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
opts = {:text => File.read(File.join(AdminData.public_dir,params[:file])), :cache => true}
|
|
12
|
+
|
|
13
|
+
case params[:file]
|
|
14
|
+
when /\.css$/i then opts[:content_type] = "text/css"
|
|
15
|
+
when /\.js$/i then opts[:content_type] = "text/javascript"
|
|
16
|
+
when /\.png$/i then opts[:content_type] = "image/png"
|
|
17
|
+
else
|
|
18
|
+
render :nothing => true, :status => 404 and return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
render opts
|
|
9
22
|
end
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
render :nothing => true, :status => 404 and return
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
# Cached list of all assets provided by admin_data
|
|
27
|
+
# It is used to ensure security in the serve method
|
|
28
|
+
def self.admin_data_assets
|
|
29
|
+
@admin_data_assets ||= (
|
|
30
|
+
Dir.glob(File.join(AdminData.public_dir,'**','*')).map do |path|
|
|
31
|
+
# we want only relative paths
|
|
32
|
+
path = path.split(AdminData.public_dir,2).last
|
|
33
|
+
end
|
|
34
|
+
)
|
|
23
35
|
end
|
|
24
|
-
render opts
|
|
25
36
|
end
|
|
26
|
-
|
|
27
37
|
end
|
|
@@ -1,125 +1,121 @@
|
|
|
1
|
-
require File.join(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@records = @klass.unscoped.paginate(h)
|
|
1
|
+
require File.join(AdminData::LIBPATH, 'admin_data', 'search')
|
|
2
|
+
|
|
3
|
+
module AdminData
|
|
4
|
+
class SearchController < ApplicationController
|
|
5
|
+
|
|
6
|
+
include Search
|
|
7
|
+
|
|
8
|
+
before_filter :get_class_from_params
|
|
9
|
+
before_filter :ensure_valid_children_klass, :only => [:quick_search]
|
|
10
|
+
before_filter :ensure_is_authorized_for_update_opration, :only => [:advance_search]
|
|
11
|
+
before_filter :set_column_type_info, :only => [:advance_search]
|
|
12
|
+
|
|
13
|
+
def quick_search
|
|
14
|
+
@page_title = "Search #{@klass.name.underscore}"
|
|
15
|
+
@order = default_order
|
|
16
|
+
|
|
17
|
+
if params[:base]
|
|
18
|
+
klass = Util.camelize_constantize(params[:base])
|
|
19
|
+
model = klass.find(params[:model_id])
|
|
20
|
+
has_many_proxy = model.send(params[:children].intern)
|
|
21
|
+
@total_num_of_children = has_many_proxy.send(:count)
|
|
22
|
+
h = { :page => params[:page], :per_page => per_page, :order => @order }
|
|
23
|
+
@records = has_many_proxy.send(:paginate, h)
|
|
24
|
+
else
|
|
25
|
+
params[:query] = params[:query].strip unless params[:query].blank?
|
|
26
|
+
cond = build_quick_search_conditions(@klass, params[:query])
|
|
27
|
+
h = { :page => params[:page], :per_page => per_page, :order => @order, :conditions => cond }
|
|
28
|
+
@records = @klass.unscoped.paginate(h)
|
|
29
|
+
end
|
|
30
|
+
respond_to {|format| format.html}
|
|
32
31
|
end
|
|
33
|
-
respond_to {|format| format.html}
|
|
34
|
-
end
|
|
35
32
|
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
def advance_search
|
|
35
|
+
@page_title = "Advance search #{@klass.name.underscore}"
|
|
36
|
+
hash = build_advance_search_conditions(@klass, params[:adv_search])
|
|
37
|
+
@relation = hash[:cond]
|
|
38
|
+
errors = hash[:errors]
|
|
39
|
+
@order = default_order
|
|
40
|
+
|
|
41
|
+
respond_to do |format|
|
|
42
|
+
format.html { render }
|
|
43
|
+
format.js {
|
|
44
|
+
|
|
45
|
+
unless hash[:errors].blank?
|
|
46
|
+
file = "#{AdminData.plugin_dir}app/views/admin_data/search/search/_errors.html.erb"
|
|
47
|
+
render :file => file, :locals => {:errors => errors}
|
|
48
|
+
return
|
|
49
|
+
end
|
|
50
|
+
if params[:admin_data_advance_search_action_type] == 'destroy'
|
|
51
|
+
handle_advance_search_action_type_destroy
|
|
52
|
+
elsif params[:admin_data_advance_search_action_type] == 'delete'
|
|
53
|
+
handle_advance_search_action_type_delete
|
|
54
|
+
else
|
|
55
|
+
@records = @relation.order(@order).paginate(:page => params[:page], :per_page => per_page)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if @success_message
|
|
59
|
+
render :json => {:success => @success_message }
|
|
60
|
+
else
|
|
61
|
+
file = "/admin_data/search/search/listing.html.erb"
|
|
62
|
+
render :partial => file, :locals => {:klass => @klass}, :layout => false
|
|
63
|
+
end
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
format.html { render }
|
|
47
|
-
format.js {
|
|
68
|
+
private
|
|
48
69
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
70
|
+
def ensure_valid_children_klass
|
|
71
|
+
if params[:base]
|
|
72
|
+
begin
|
|
73
|
+
model_klass = Util.camelize_constantize(params[:base])
|
|
74
|
+
rescue NameError => e #incase params[:base] is junk value
|
|
75
|
+
render :text => "#{params[:base]} is an invalid value", :status => :not_found
|
|
52
76
|
return
|
|
53
77
|
end
|
|
54
|
-
if params[:
|
|
55
|
-
|
|
56
|
-
elsif params[:admin_data_advance_search_action_type] == 'delete'
|
|
57
|
-
handle_advance_search_action_type_delete
|
|
78
|
+
if ActiveRecordUtil.declared_has_many_association_names(model_klass).include?(params[:children]) || ActiveRecordUtil.declared_habtm_association_names(model_klass).include?(params[:children])
|
|
79
|
+
#proceed
|
|
58
80
|
else
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if @success_message
|
|
63
|
-
render :json => {:success => @success_message }
|
|
64
|
-
else
|
|
65
|
-
file = "/admin_data/search/search/listing.html.erb"
|
|
66
|
-
render :partial => file, :locals => {:klass => @klass}, :layout => false
|
|
81
|
+
render :text => "#{params[:children]} is not a valid has_many association", :status => :not_found
|
|
82
|
+
return
|
|
67
83
|
end
|
|
68
|
-
|
|
84
|
+
end
|
|
69
85
|
end
|
|
70
|
-
end
|
|
71
86
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if params[:base]
|
|
76
|
-
begin
|
|
77
|
-
model_klass = AdminData::Util.camelize_constantize(params[:base])
|
|
78
|
-
rescue NameError => e #incase params[:base] is junk value
|
|
79
|
-
render :text => "#{params[:base]} is an invalid value", :status => :not_found
|
|
80
|
-
return
|
|
81
|
-
end
|
|
82
|
-
#TODO write test for this condition
|
|
83
|
-
if AdminData::ActiveRecordUtil.declared_has_many_association_names(model_klass).include?(params[:children]) || AdminData::ActiveRecordUtil.declared_habtm_association_names(model_klass).include?(params[:children])
|
|
84
|
-
#proceed
|
|
85
|
-
else
|
|
86
|
-
render :text => "#{params[:children]} is not a valid has_many association", :status => :not_found
|
|
87
|
-
return
|
|
87
|
+
def ensure_is_authorized_for_update_opration
|
|
88
|
+
if %w(destroy delete).include? params[:admin_data_advance_search_action_type]
|
|
89
|
+
render :text => 'not authorized' unless is_allowed_to_update?
|
|
88
90
|
end
|
|
89
91
|
end
|
|
90
|
-
end
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
def handle_advance_search_action_type_delete
|
|
94
|
+
count = @relation.count
|
|
95
|
+
@relation.delete_all
|
|
96
|
+
@success_message = "#{count} #{Util.pluralize(count, 'record')} deleted"
|
|
95
97
|
end
|
|
96
|
-
end
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
def handle_advance_search_action_type_destroy
|
|
100
|
+
count = @relation.count
|
|
101
|
+
@relation.find_in_batches do |group|
|
|
102
|
+
group.each {|record| record.destroy }
|
|
103
|
+
end
|
|
104
|
+
@success_message = "#{count} #{Util.pluralize(count, 'record')} destroyed"
|
|
105
|
+
end
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@relation.find_in_batches do |group|
|
|
107
|
-
group.each {|record| record.destroy }
|
|
107
|
+
def default_order
|
|
108
|
+
params[:sortby] || "#{@klass.send(:table_name)}.#{@klass.send(:primary_key)} desc"
|
|
108
109
|
end
|
|
109
|
-
@success_message = "#{count} #{AdminData::Util.pluralize(count, 'record')} destroyed"
|
|
110
|
-
end
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
def set_column_type_info
|
|
112
|
+
column_type_info = @klass.columns.collect { |column|
|
|
113
|
+
#JSLint complains if a hash has key named boolean. So I am changing the key to booleant
|
|
114
|
+
column_type = (column.type.to_s == 'boolean') ? 'booleant' : column.type.to_s
|
|
115
|
+
%Q{ "#{column.name}":"#{column_type}" }
|
|
116
|
+
}.join(',')
|
|
117
|
+
@column_type_info = "{#{column_type_info}}"
|
|
118
|
+
end
|
|
115
119
|
|
|
116
|
-
def set_column_type_info
|
|
117
|
-
column_type_info = @klass.columns.collect { |column|
|
|
118
|
-
#JSLint complains if a hash has key named boolean. So I am changing the key to booleant
|
|
119
|
-
column_type = (column.type.to_s == 'boolean') ? 'booleant' : column.type.to_s
|
|
120
|
-
%Q{ "#{column.name}":"#{column_type}" }
|
|
121
|
-
}.join(',')
|
|
122
|
-
@column_type_info = "{#{column_type_info}}"
|
|
123
120
|
end
|
|
124
|
-
|
|
125
121
|
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,287 @@
|
|
|
1
|
+
module AdminData
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
|
|
4
|
+
def column_title(klass, column)
|
|
5
|
+
AdminData.config.column_headers[klass.name].try(:fetch,column.intern, nil) || column
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# AdminData.config.columns_order might not list all the columns of a given table. However
|
|
9
|
+
# the listed columns should be at the front in the order mentioned. Primary key will also
|
|
10
|
+
# be the first column. Consumer might define a new column name that is not listed a column.
|
|
11
|
+
#
|
|
12
|
+
def columns_order(klass)
|
|
13
|
+
columns_symbol = klass.columns.map {|e| e.name.intern}
|
|
14
|
+
|
|
15
|
+
# created_at and updated_at should be at the very end by default
|
|
16
|
+
if columns_symbol.include? :created_at
|
|
17
|
+
columns_symbol = (columns_symbol - [:created_at]) + [:created_at]
|
|
18
|
+
end
|
|
19
|
+
if columns_symbol.include? :updated_at
|
|
20
|
+
columns_symbol = (columns_symbol - [:updated_at]) + [:updated_at]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if requested_order = AdminData.config.columns_order[klass.name]
|
|
24
|
+
primary_key = klass.send(:primary_key).intern
|
|
25
|
+
order = [primary_key] + requested_order
|
|
26
|
+
order.uniq!
|
|
27
|
+
# add the columns not covered by user at the end of the list
|
|
28
|
+
sorted_columns = order + (columns_symbol - order)
|
|
29
|
+
sorted_columns.map(&:to_s)
|
|
30
|
+
else
|
|
31
|
+
columns_symbol.map(&:to_s)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def total_records_info(klass)
|
|
36
|
+
'(Total ' + pluralize(klass.count, 'record') + ' )'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def search_result_title(total_num_of_children, records)
|
|
40
|
+
output = []
|
|
41
|
+
if params[:base]
|
|
42
|
+
label = params[:base].camelize + ' ID ' + params[:model_id]
|
|
43
|
+
output << link_to(label, admin_data_path(:klass => params[:base], :id => params[:model_id]))
|
|
44
|
+
output << 'has'
|
|
45
|
+
output << pluralize(total_num_of_children, params[:klass])
|
|
46
|
+
|
|
47
|
+
elsif !params[:query].blank? || params[:adv_search]
|
|
48
|
+
output << 'Search result:'
|
|
49
|
+
output << pluralize(records.total_entries, 'record')
|
|
50
|
+
output << 'found'
|
|
51
|
+
|
|
52
|
+
else
|
|
53
|
+
output << 'All '
|
|
54
|
+
output << params[:klass].camelize
|
|
55
|
+
output << 'records'
|
|
56
|
+
end
|
|
57
|
+
output.join(' ').html_safe
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def column_native(klass, column)
|
|
61
|
+
klass.send(:columns).select {|r| r.instance_variable_get('@name') == column}.first || column
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def has_one(model, klass)
|
|
65
|
+
tmp = AdminData::ActiveRecordUtil.declared_has_one_association_names(klass)
|
|
66
|
+
tmp.inject('') do |output, ho|
|
|
67
|
+
begin
|
|
68
|
+
label = ho
|
|
69
|
+
if model.send(ho)
|
|
70
|
+
output << link_to(label, admin_data_path(:klass => ho.underscore, :id => model.send(ho)))
|
|
71
|
+
else
|
|
72
|
+
output << label
|
|
73
|
+
end
|
|
74
|
+
rescue => e
|
|
75
|
+
Rails.logger.debug AdminData::Util.exception_info(e)
|
|
76
|
+
end
|
|
77
|
+
output
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def has_many_data(model, klass)
|
|
82
|
+
array = AdminData::ActiveRecordUtil.declared_has_many_association_names(klass).map do |m|
|
|
83
|
+
begin
|
|
84
|
+
count = model.send(m.intern).count
|
|
85
|
+
label = m.to_s + '(' + count.to_s + ')'
|
|
86
|
+
output = label
|
|
87
|
+
if count > 0
|
|
88
|
+
has_many_klass_name = AdminData::ActiveRecordUtil.klass_for_association_type_and_name(model.class, :has_many, m).name.underscore
|
|
89
|
+
output = link_to(label, admin_data_search_path( :klass => has_many_klass_name,
|
|
90
|
+
:children => m,
|
|
91
|
+
:base => klass.name.underscore,
|
|
92
|
+
:model_id => model.id))
|
|
93
|
+
end
|
|
94
|
+
rescue => e
|
|
95
|
+
Rails.logger.debug AdminData::Util.exception_info(e)
|
|
96
|
+
end
|
|
97
|
+
output
|
|
98
|
+
end
|
|
99
|
+
array.join(', ')
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def belongs_to_data(model, klass)
|
|
103
|
+
AdminData::ActiveRecordUtil.declared_belongs_to_association_names(klass).map do |assoc_name|
|
|
104
|
+
begin
|
|
105
|
+
output = assoc_name
|
|
106
|
+
if belongs_to_record = model.send(assoc_name)
|
|
107
|
+
output = link_to(assoc_name, admin_data_path(:klass => belongs_to_record.class.name.underscore, :id => belongs_to_record.id))
|
|
108
|
+
end
|
|
109
|
+
rescue => e
|
|
110
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
111
|
+
end
|
|
112
|
+
output
|
|
113
|
+
end.join(', ')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def habtm_data(model, klass)
|
|
117
|
+
AdminData::ActiveRecordUtil.declared_habtm_association_names(klass).map do |assoc_name|
|
|
118
|
+
begin
|
|
119
|
+
count = model.send(assoc_name.intern).count
|
|
120
|
+
label = assoc_name + '(' + count.to_s + ')'
|
|
121
|
+
output = label
|
|
122
|
+
|
|
123
|
+
if count > 0 then
|
|
124
|
+
has_many_klass_name = AdminData::ActiveRecordUtil.klass_for_association_type_and_name(model.class, :has_and_belongs_to_many, assoc_name).name.underscore
|
|
125
|
+
output = link_to(label, admin_data_search_path( :klass => has_many_klass_name,
|
|
126
|
+
:children => assoc_name,
|
|
127
|
+
:base => klass.name.underscore,
|
|
128
|
+
:model_id => model.id))
|
|
129
|
+
end
|
|
130
|
+
rescue => e
|
|
131
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
132
|
+
end
|
|
133
|
+
output
|
|
134
|
+
end.join(', ')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def breadcrum(&block)
|
|
138
|
+
render(:partial => '/admin_data/shared/breadcrum', :locals => {:data => capture(&block)})
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def form_field(klass, model, col, f)
|
|
142
|
+
html = []
|
|
143
|
+
column_value = model.send(col.name)
|
|
144
|
+
|
|
145
|
+
if klass.serialized_attributes.has_key?(col.name)
|
|
146
|
+
return AdminData::Util.get_serialized_value(html,column_value)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
if col.primary
|
|
150
|
+
html << model.new_record? ? '(auto)' : model.id
|
|
151
|
+
elsif get_reflection_for_column(klass, col) && AdminData.config.drop_down_for_associations[klass.name]
|
|
152
|
+
form_field_for_association_records(klass, col, f, html)
|
|
153
|
+
else
|
|
154
|
+
handle_column_type(col, html, model, column_value, f)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def form_field_for_association_records(klass, col, f, html)
|
|
160
|
+
begin
|
|
161
|
+
reflection = get_reflection_for_column(klass, col)
|
|
162
|
+
|
|
163
|
+
# in some edge cases following code throws exception. investigating ..
|
|
164
|
+
options = reflection.options
|
|
165
|
+
if options.keys.include?(:polymorphic) && options.fetch(:polymorphic)
|
|
166
|
+
build_text_field(html, f, col)
|
|
167
|
+
else
|
|
168
|
+
ref_klass = reflection.klass
|
|
169
|
+
association_name = ref_klass.columns.map(&:name).include?('name') ? :name : ref_klass.primary_key
|
|
170
|
+
all_for_dropdown = ref_klass.all(:order => "#{association_name} asc")
|
|
171
|
+
html << f.collection_select(col.name, all_for_dropdown, :id, association_name, :include_blank => true)
|
|
172
|
+
end
|
|
173
|
+
html.join
|
|
174
|
+
rescue Exception => e
|
|
175
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
176
|
+
'could not retrieve' # returning nil
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def form_field_for_habtm_records(klass, model, f, html)
|
|
181
|
+
begin
|
|
182
|
+
html = []
|
|
183
|
+
AdminData::ActiveRecordUtil.delcared_habtm_association_names(klass).each do |k|
|
|
184
|
+
assoc_klass = AdminData::Util.get_class_name_for_habtm_association(model, k)
|
|
185
|
+
|
|
186
|
+
html << "<div class='col_box'>"
|
|
187
|
+
html << " <span class='col_name'>#{assoc_klass.table_name}</span>"
|
|
188
|
+
html << " <span class='col_type'>[integer]</span>"
|
|
189
|
+
html << "</div>"
|
|
190
|
+
|
|
191
|
+
order_by = assoc_klass.columns.map(&:name).include?('name') ? :name : assoc_klass.primary_key
|
|
192
|
+
all = assoc_klass.all(:order => order_by)
|
|
193
|
+
selected = model.send(assoc_klass.table_name).map{|e| e.id}
|
|
194
|
+
html << f.collection_select(assoc_klass.table_name, all, :id, order_by,
|
|
195
|
+
{:include_blank => false, :selected => selected},
|
|
196
|
+
{:multiple => true, :size => (all.count > 10 ? 8 : 4)})
|
|
197
|
+
end
|
|
198
|
+
html.join
|
|
199
|
+
rescue Exception => e
|
|
200
|
+
Rails.logger.info AdminData::Util.exception_info(e)
|
|
201
|
+
'could not retrieve' # returning nil
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def handle_column_type(col, html, model, column_value, f)
|
|
206
|
+
case col.type
|
|
207
|
+
when :text
|
|
208
|
+
html << f.text_area(col.name, :rows => 6, :cols => 70)
|
|
209
|
+
|
|
210
|
+
when :datetime
|
|
211
|
+
if ['created_at', 'updated_at'].include?(col.name)
|
|
212
|
+
html << '(auto)'
|
|
213
|
+
else
|
|
214
|
+
value = params[:action] == 'new' ? Time.now : column_value
|
|
215
|
+
year_value = value.year if value
|
|
216
|
+
datetime_selects = f.datetime_select(col.name, :include_blank => true)
|
|
217
|
+
html << datetime_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
when :date
|
|
221
|
+
value = params[:action] == 'new' ? Time.now : column_value
|
|
222
|
+
year_value = value.year if value
|
|
223
|
+
date_selects = f.date_select(col.name, :discard_year => true, :include_blank => true)
|
|
224
|
+
html << date_selects.gsub('type="hidden"', 'type="text" size="4" class="nice-field"')
|
|
225
|
+
|
|
226
|
+
when :time
|
|
227
|
+
# time_select method of rails is buggy and is causing problem
|
|
228
|
+
# 1 error(s) on assignment of multiparameter attributes
|
|
229
|
+
#
|
|
230
|
+
# will try again this method with Rails 3
|
|
231
|
+
#html << f.time_select(col.name, :include_blank => true, :include_seconds => true)
|
|
232
|
+
|
|
233
|
+
when :boolean
|
|
234
|
+
html << f.select(col.name, [['True', true], ['False', false]], :include_blank => true)
|
|
235
|
+
|
|
236
|
+
else
|
|
237
|
+
build_text_field(html, f, col)
|
|
238
|
+
end
|
|
239
|
+
html.join
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def build_text_field(html, f, col)
|
|
244
|
+
options = {:class => 'nice-field'}
|
|
245
|
+
if AdminData.config.ignore_column_limit
|
|
246
|
+
options[:size] = 60
|
|
247
|
+
options[:maxlength] = 255
|
|
248
|
+
else
|
|
249
|
+
options[:size] = (col && col.limit && col.limit < 60) ? col.limit : 60
|
|
250
|
+
options[:maxlength] = col.limit if col.limit
|
|
251
|
+
end
|
|
252
|
+
html << f.text_field(col.name, options)
|
|
253
|
+
html.join
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# uses truncate method
|
|
257
|
+
# options supports :limit which is applied if the column type is string or text.
|
|
258
|
+
# calls the inspect method to convert to a string if the column is serialized.
|
|
259
|
+
# TODO rspec test limit option
|
|
260
|
+
def get_value_for_column(column, model, options = {})
|
|
261
|
+
options.reverse_merge!(:limit => 400)
|
|
262
|
+
|
|
263
|
+
value = AdminData::Util.custom_value_for_column(column, model)
|
|
264
|
+
|
|
265
|
+
if column.is_a?(String)
|
|
266
|
+
value
|
|
267
|
+
elsif column.type == :datetime
|
|
268
|
+
value.strftime('%d-%B-%Y %H:%M:%S %p') unless value.blank?
|
|
269
|
+
elsif column.type == :string || column.type == :text
|
|
270
|
+
value = value.inspect if model.class.serialized_attributes.keys.include?(column.name)
|
|
271
|
+
return value if options[:limit].blank?
|
|
272
|
+
begin
|
|
273
|
+
truncate(value,:length => options[:limit])
|
|
274
|
+
rescue # truncate method failed
|
|
275
|
+
'<actual data is not being shown because truncate method failed.>'
|
|
276
|
+
end
|
|
277
|
+
else
|
|
278
|
+
value.to_s
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def get_reflection_for_column(klass, col)
|
|
283
|
+
klass.reflections.values.detect { |reflection| reflection.primary_key_name.to_sym == col.name.to_sym }
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
end
|
|
287
|
+
end
|