rails_info 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +58 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/rails_info/application.js +6 -0
  5. data/app/assets/javascripts/rails_info/base.js.coffee +6 -0
  6. data/app/assets/javascripts/rails_info/bootstrap.js.coffee +4 -0
  7. data/app/assets/stylesheets/rails_info/application.css +14 -0
  8. data/app/assets/stylesheets/rails_info/base.css.scss +22 -0
  9. data/app/assets/stylesheets/rails_info/bootstrap_and_overrides.css.less +63 -0
  10. data/app/assets/stylesheets/rails_info/exception.css +17 -0
  11. data/app/assets/stylesheets/rails_info/exception/base.css.scss +31 -0
  12. data/app/assets/stylesheets/rails_info/exception/pygments.css.erb +5 -0
  13. data/app/controllers/rails_info/data_controller.rb +9 -0
  14. data/app/controllers/rails_info/logs/server_controller.rb +10 -0
  15. data/app/controllers/rails_info/logs/test/rspec_controller.rb +16 -0
  16. data/app/controllers/rails_info/model_controller.rb +5 -0
  17. data/app/controllers/rails_info/properties_controller.rb +4 -0
  18. data/app/controllers/rails_info/routes_controller.rb +4 -0
  19. data/app/controllers/rails_info/stack_traces_controller.rb +11 -0
  20. data/app/controllers/rails_info_controller.rb +16 -0
  21. data/app/helpers/rails_info/resources_helper.rb +194 -0
  22. data/app/presenters/rails_info/code_presenter.rb +63 -0
  23. data/app/presenters/rails_info/data/object_presenter.rb +34 -0
  24. data/app/presenters/rails_info/data/row_set_presenter.rb +38 -0
  25. data/app/presenters/rails_info/data_presenter.rb +21 -0
  26. data/app/presenters/rails_info/logs/server/action_presenter.rb +109 -0
  27. data/app/presenters/rails_info/logs/server_presenter.rb +57 -0
  28. data/app/presenters/rails_info/logs/test/rspec/file_presenter.rb +87 -0
  29. data/app/presenters/rails_info/logs/test/rspec_presenter.rb +32 -0
  30. data/app/presenters/rails_info/model_presenter.rb +68 -0
  31. data/app/presenters/rails_info/presenter.rb +19 -0
  32. data/app/presenters/rails_info/stack_trace_presenter.rb +98 -0
  33. data/app/views/layouts/_layout.html.erb +19 -0
  34. data/app/views/layouts/rails_info.html.erb +1 -0
  35. data/app/views/layouts/rails_info/exception.html.erb +1 -0
  36. data/app/views/layouts/shared/_navigation.html.erb +7 -0
  37. data/app/views/rails_info/data/index.html.erb +23 -0
  38. data/app/views/rails_info/logs/server/_table.html.erb +16 -0
  39. data/app/views/rails_info/logs/server/new.html.erb +19 -0
  40. data/app/views/rails_info/logs/test/rspec/new.html.erb +10 -0
  41. data/app/views/rails_info/model/index.html.erb +14 -0
  42. data/app/views/rails_info/properties/index.html.erb +1 -0
  43. data/app/views/rails_info/routes/index.html.erb +18 -0
  44. data/app/views/rails_info/stack_traces/_accordion.html.erb +1 -0
  45. data/app/views/rails_info/stack_traces/_form.html.erb +11 -0
  46. data/app/views/rails_info/stack_traces/_with_request_and_response.html.erb +16 -0
  47. data/app/views/rails_info/stack_traces/new.html.erb +10 -0
  48. data/config/navigation.rb +20 -0
  49. data/config/routes.rb +20 -0
  50. data/lib/rails_info.rb +19 -0
  51. data/lib/rails_info/controller.rb +2 -0
  52. data/lib/rails_info/controller/exception_diagnostics.rb +28 -0
  53. data/lib/rails_info/data.rb +55 -0
  54. data/lib/rails_info/engine.rb +9 -0
  55. data/lib/rails_info/logs.rb +2 -0
  56. data/lib/rails_info/logs/server.rb +230 -0
  57. data/lib/rails_info/logs/test.rb +2 -0
  58. data/lib/rails_info/logs/test/rspec.rb +160 -0
  59. data/lib/rails_info/model.rb +221 -0
  60. data/lib/rails_info/stack_trace.rb +155 -0
  61. data/lib/rails_info/version.rb +3 -0
  62. data/lib/tasks/rails_info_tasks.rake +4 -0
  63. data/spec/dummy/README.rdoc +261 -0
  64. data/spec/dummy/Rakefile +7 -0
  65. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  66. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  67. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  68. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  69. data/spec/dummy/app/models/user.rb +3 -0
  70. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  71. data/spec/dummy/config.ru +4 -0
  72. data/spec/dummy/config/application.rb +59 -0
  73. data/spec/dummy/config/boot.rb +10 -0
  74. data/spec/dummy/config/database.yml +42 -0
  75. data/spec/dummy/config/environment.rb +5 -0
  76. data/spec/dummy/config/environments/development.rb +39 -0
  77. data/spec/dummy/config/environments/production.rb +69 -0
  78. data/spec/dummy/config/environments/test.rb +39 -0
  79. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  80. data/spec/dummy/config/initializers/inflections.rb +15 -0
  81. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  82. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  83. data/spec/dummy/config/initializers/session_store.rb +8 -0
  84. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  85. data/spec/dummy/config/locales/en.yml +5 -0
  86. data/spec/dummy/config/routes.rb +2 -0
  87. data/spec/dummy/log/development.log +4876 -0
  88. data/spec/dummy/public/404.html +26 -0
  89. data/spec/dummy/public/422.html +26 -0
  90. data/spec/dummy/public/500.html +25 -0
  91. data/spec/dummy/public/favicon.ico +0 -0
  92. data/spec/dummy/script/rails +6 -0
  93. metadata +274 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ = RailsInfo
2
+
3
+ Wiki[https://github.com/applicat/rails_info/wiki]
4
+
5
+ Experimental engine for a rails application besides admin and continous integration web interface which extends standard /rails/info (properties through public.html iframe and on Rails 3 Edge / Rails 4 also the routes action) about some extra information resources in development environment.
6
+
7
+ It should be the place for other rake commands besides "rake routes" such as brakeman or best practices.
8
+
9
+ Prepare for sporadic Ruby segmentation faults caused by the Python powered syntax highlighter pygments in the early stages of this project (at least under Ruby 1.9.3 & Rails 3.2.6 on MacOS).
10
+ There will be a configuration option for deactivating syntax highlighting soon for the time being without a solution for this problem.
11
+
12
+ Tested on MacOS with: Rails 3.1 & Ruby 1.9.2, Rails 3.2.6 & Ruby 1.9.3.
13
+
14
+ == Installation
15
+
16
+ In <b>Rails 3</b>, add this under your development group to the Gemfile of your Rails 3 application and run the +bundle+ command.
17
+
18
+ gem "rails_info"
19
+
20
+ == Getting Started
21
+
22
+ === 1) Request the Web interface
23
+
24
+ Just start your Rails 3 application server and request the following page in your browser.
25
+
26
+ http://localhost:3001/rails/info
27
+
28
+ === 2) Custom Exception Stack Trace View
29
+
30
+ Add the following line at the top of your ApplicationController to replace the standard stack trace view by a customized version which displays the code snippet for each file of the stack trace inline:
31
+
32
+ include RailsInfo::Controller::ExceptionDiagnostics
33
+
34
+ Consider those sporadic Ruby segmentation faults mentioned above when you include this line ;-)
35
+
36
+ === 3) RSpec Log
37
+
38
+ Write the result of an rspec command to log/rspec.log
39
+
40
+ bundle exec rspec spec/whatever_you_want > log/rspec.log
41
+
42
+ Run your rails development server if not already started and request the following page:
43
+
44
+ http://localhost:3000/rails/info/logs/test/rspec
45
+
46
+ == Wiki Docs
47
+
48
+ * TODO
49
+
50
+ == Contribution
51
+
52
+ Just follow the screencast of Ryan Bates on railscasts.com:
53
+
54
+ http://railscasts.com/episodes/300-contributing-to-open-source
55
+
56
+ == License
57
+
58
+ This project uses MIT-LICENSE.
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'RailsInfo'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,6 @@
1
+ //= require jquery
2
+ //= require jquery.ui.all
3
+ //= require jquery_ujs
4
+ //= require twitter/bootstrap
5
+ //= require ./base
6
+ //= require ./bootstrap
@@ -0,0 +1,6 @@
1
+ $(document).ready ->
2
+ $( ".accordions" ).each (k, v) ->
3
+ $(v).accordion({ autoHeight: false });
4
+
5
+ $(".tabs").each (k, v) ->
6
+ $(v).tabs({ autoHeight: false });
@@ -0,0 +1,4 @@
1
+ jQuery ->
2
+ $("a[rel=popover]").popover()
3
+ $(".tooltip").tooltip()
4
+ $("a[rel=tooltip]").tooltip()
@@ -0,0 +1,14 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require 'rails_info/bootstrap_and_overrides'
13
+ *= require 'rails_info/base'
14
+ */
@@ -0,0 +1,22 @@
1
+ /*
2
+ *= require jquery.ui.all
3
+ */
4
+
5
+ /*body {
6
+ font-family: Arial;
7
+ }*/
8
+
9
+ .ui-widget {
10
+ font-family: Arial;
11
+ font-size: 10px;
12
+ }
13
+
14
+ html, body, div, span {
15
+ font-family: Arial;
16
+ font-size: 10px;
17
+ }
18
+
19
+ .nav a {
20
+ font-family: Arial;
21
+ font-size: 10px;
22
+ }
@@ -0,0 +1,63 @@
1
+ @import "twitter/bootstrap/bootstrap";
2
+ /*body {
3
+ padding-top: 60px;
4
+ padding-left: 20px;
5
+ }*/
6
+
7
+ @import "twitter/bootstrap/responsive";
8
+
9
+ pre {
10
+ background-color: white;
11
+ border: 0px;
12
+ border-radius: 0px;
13
+ display: block;
14
+ font-size: 10px;
15
+ line-height: 18px;
16
+ margin: 0px;
17
+ padding: 0px;
18
+ white-space: pre-wrap;
19
+ word-wrap: break-word;
20
+ }
21
+
22
+ code, pre {
23
+ font-family: Arial;
24
+ }
25
+
26
+ code {
27
+ border-radius: 0px;
28
+ border-width: 0px;
29
+ color: black;
30
+ background-color: white;
31
+ font-size: 10px;
32
+ padding: 0px;
33
+ }
34
+
35
+ .nav a {
36
+ font-size:14px ! important;
37
+ }
38
+
39
+ // Set the correct sprite paths
40
+ @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
41
+ @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');
42
+
43
+ // Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
44
+ // Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
45
+ // have the proper paths. So for now we use the absolute path.
46
+ @fontAwesomeEotPath: '/assets/fontawesome-webfont.eot';
47
+ @fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff';
48
+ @fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf';
49
+ @fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg';
50
+
51
+ // Font Awesome
52
+ @import "fontawesome";
53
+
54
+ // Your custom LESS stylesheets goes here
55
+ //
56
+ // Since bootstrap was imported above you have access to its mixins which
57
+ // you may use and inherit here
58
+ //
59
+ // If you'd like to override bootstrap's own variables, you can do so here as well
60
+ // See http://twitter.github.com/bootstrap/less.html for their names and documentation
61
+ //
62
+ // Example:
63
+ // @linkColor: #ff0000;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require jquery.ui.all
13
+ *= require rails_info/bootstrap_and_overrides
14
+ *= require rails_info/base
15
+ *= require rails_info/exception/base
16
+ *= require rails_info/exception/pygments
17
+ */
@@ -0,0 +1,31 @@
1
+ table {
2
+ padding: 0px; margin:0px;
3
+ font-family: Arial;
4
+ border: 1px solid black;
5
+ border-collapse: collapse;
6
+ }
7
+
8
+ td {
9
+ padding: 0px 5px;
10
+ margin: 0px;
11
+ border: 1px solid black;
12
+ vertical-align:top;
13
+ }
14
+
15
+ td.number {
16
+ font-size: 12px;
17
+ vertical-align:bottom;
18
+ }
19
+
20
+ pre {
21
+ font-size:14px;
22
+ display: inline;
23
+ }
24
+
25
+ pre.stack_trace_message {
26
+ display: block;
27
+ background-color: #EEEEEE;
28
+ font-size: 11px;
29
+ padding: 10px;
30
+ white-space: pre-wrap;
31
+ }
@@ -0,0 +1,5 @@
1
+ <%= Pygments.css(style: "colorful") %>
2
+
3
+ .hll, .hll span {
4
+ background-color: #FFFFCC ! important;
5
+ }
@@ -0,0 +1,9 @@
1
+ class RailsInfo::DataController < RailsInfoController
2
+ def index
3
+ @rails_info_data = ::RailsInfo::DataPresenter.new(view_context)
4
+ end
5
+
6
+ def update_multiple_data
7
+ RailsInfo::Data.update_multiple_data(params[:data]) if params[:delete]
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class RailsInfo::Logs::ServerController < RailsInfoController
2
+ def new
3
+ @rails_info_log = ::RailsInfo::Logs::ServerPresenter.new(view_context, log: params[:log], debug: params[:debug])
4
+ end
5
+
6
+ def update
7
+ @rails_info_log = ::RailsInfo::Logs::ServerPresenter.new(log: params[:log], debug: params[:debug])
8
+ render 'new'
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ class RailsInfo::Logs::Test::RspecController < RailsInfoController
2
+ layout 'rails_info/exception'
3
+
4
+ def new
5
+ @rails_info_log = ::RailsInfo::Logs::Test::RspecPresenter.new(
6
+ view_context, log: {rails_root: Rails.root.to_s}.merge(params[:log] || {}), debug: params[:debug]
7
+ )
8
+ end
9
+
10
+ def update
11
+ @rails_info_log = ::RailsInfo::Logs::Test::RspecPresenter.new(
12
+ view_context, log: params[:log], debug: params[:debug]
13
+ )
14
+ render 'new'
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class RailsInfo::ModelController < RailsInfoController
2
+ def index
3
+ @rails_info_model = ::RailsInfo::ModelPresenter.new(view_context)
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ class RailsInfo::PropertiesController < RailsInfoController
2
+ def index
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ class RailsInfo::RoutesController < RailsInfoController
2
+ def index
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ class RailsInfo::StackTracesController < RailsInfoController
2
+ layout 'rails_info/exception'
3
+
4
+ def new
5
+ end
6
+
7
+ def create
8
+ @stack_trace = RailsInfo::StackTracePresenter.new(view_context, stack_trace: params[:stack_trace])
9
+ render 'new'
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ class RailsInfoController < Rails::InfoController
2
+ include ::RailsInfo::Controller::ExceptionDiagnostics
3
+
4
+ before_filter :check_if_all_requests_local
5
+
6
+ #TODO: should inherit from ApplicationController especially for authentification & authorization purposes
7
+ layout 'rails_info'
8
+
9
+ private
10
+
11
+ def check_if_all_requests_local
12
+ unless Rails.application.config.consider_all_requests_local || request.local?
13
+ render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,194 @@
1
+ module RailsInfo::ResourcesHelper
2
+ TRANSLATED_COLUMNS = []
3
+
4
+ def resource_tree(presenter, parent_id = '')
5
+ content = ""
6
+
7
+ presenter.each do |title, resource_presenter|
8
+ id = parent_id.blank? ? title.parameterize : "#{parent_id}-#{title.parameterize}"
9
+
10
+ if resource_presenter[:sub_collection]
11
+ content += content_tag(:li, raw(title) + resource_tree(resource_presenter[:sub_collection], id))
12
+ else
13
+ content += content_tag(:li, title)
14
+ end
15
+ end
16
+
17
+ content_tag(:ul, raw(content))
18
+ end
19
+
20
+ def resource_presenter_renderer(presenter)
21
+ params['display_type'] == 'flat' ? raw(flat_resource_presenter_renderer(presenter)) : nested_resource_presenter_renderer(presenter)
22
+ end
23
+
24
+ def nested_resource_presenter_renderer(presenter, parent_id = '')
25
+ tabs_for do |tab|
26
+ presenter.each do |title,resource_presenter|
27
+ id = parent_id.blank? ? title.parameterize : "#{parent_id}-#{title.parameterize}"
28
+ tab_title = resource_presenter[:group_by] ? "#{title} (Group by: #{resource_presenter[:group_by]})" : title
29
+ tab.create(id, tab_title) do
30
+ content = ""
31
+
32
+ resource_presenter[:collection] = [resource_presenter[:collection]] unless resource_presenter[:collection].respond_to?('first')
33
+
34
+ if resource_presenter[:collection]
35
+ content = render(
36
+ 'shared/resource/section', {
37
+ :title => title, :collection => resource_presenter[:collection], :group_by => resource_presenter[:group_by],
38
+ :group_by_values => resource_presenter[:group_by_values]
39
+ }
40
+ )
41
+ end
42
+
43
+ content += nested_resource_presenter_renderer(resource_presenter[:sub_collection], id) if resource_presenter[:sub_collection]
44
+
45
+ raw content
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def flat_resource_presenter_renderer(presenter, level = '')
52
+ content = ""
53
+
54
+ presenter.each do |title,resource_presenter|
55
+ content += render('shared/resource/section', :title => "#{level} #{title}", :collection => resource_presenter[:collection]) if resource_presenter[:collection]
56
+
57
+ content += flat_resource_presenter_renderer(resource_presenter[:sub_collection], "#{level} -") if resource_presenter[:sub_collection]
58
+ end
59
+
60
+ content
61
+ end
62
+
63
+ def collection_map(collection_map)
64
+ collection = []
65
+
66
+ collection_map.each do |sub_collection|
67
+ sub_collection.each do |resource|
68
+ collection << resource
69
+ end
70
+ end
71
+
72
+ collection_map.clear
73
+
74
+ collection
75
+ end
76
+
77
+ def grouped_collection(title, collection, group_by)
78
+ @grouped_collections ||= {}
79
+
80
+ collection_key = "#{title}-{group_by}-#{collection.length}"
81
+
82
+ return @grouped_collections[collection_key] if @grouped_collections[collection_key]
83
+
84
+ @grouped_collections[collection_key] = ActiveSupport::OrderedHash.new
85
+
86
+ collection.each do |element|
87
+ if element.is_a?(Hash)
88
+ key = element[group_by.to_s]
89
+ elsif element.respond_to?('translation') && element.translation.respond_to?(group_by)
90
+ key = element.translation.send(group_by)
91
+ else
92
+ key = element.send(group_by)
93
+ end
94
+
95
+ if @grouped_collections[collection_key].has_key?(key)
96
+ @grouped_collections[collection_key][key] << element
97
+ else
98
+ @grouped_collections[collection_key][key] = [element]
99
+ end
100
+ end
101
+
102
+ @grouped_collections[collection_key]
103
+ end
104
+
105
+ def group_columns(title, collection, group_by = nil, group_by_values = nil)
106
+ collection_columns = grouped_collection(title, collection, group_by).keys
107
+
108
+ if group_by_values.is_a?(Array)
109
+ group_by_values.delete_if {|c| !collection_columns.include?(c) }
110
+ collection_columns.delete_if {|c| group_by_values.include?(c) }
111
+ group_by_values + collection_columns
112
+ else
113
+ collection_columns
114
+ end
115
+ end
116
+
117
+ def resource_columns(collection, group_by = nil)
118
+ collection_columns = []
119
+
120
+ if collection.first.is_a?(Array)
121
+ raise "Please wrap the :collection by help.collection_map: #{collection.inspect}"
122
+ elsif collection.first.is_a?(Hash)
123
+ collection_columns = collection.first[:class].columns.map(&:name)
124
+ else
125
+ collection_columns = collection.first.attributes.keys
126
+ end
127
+
128
+ exclude_columns = [
129
+ 'current_code', 'last_code' # WorkflowControllerType binary columns
130
+ ]
131
+
132
+ exclude_columns << group_by if group_by
133
+
134
+ collection_columns.delete_if {|c| exclude_columns.include?(c) }
135
+
136
+ unless collection.first.is_a?(Hash)
137
+ TRANSLATED_COLUMNS.each do |translated_column|
138
+ if !collection.first.attributes[translated_column] && collection.first.respond_to?('translation') && collection.first.translation.respond_to?(translated_column)
139
+ collection_columns << translated_column
140
+ end
141
+ end
142
+ end
143
+
144
+ first_columns = ['id', 'sort_order', 'order', 'position', 'type', 'state', 'name', 'label', 'title', 'slug']
145
+ first_columns.delete_if {|c| !collection_columns.include?(c) }
146
+ collection_columns.delete_if {|c| first_columns.include?(c) }
147
+
148
+ bool_columns = ['final' ,'public', 'hidden']
149
+ bool_columns.delete_if {|c| !collection_columns.include?(c) }
150
+ collection_columns.delete_if {|c| bool_columns.include?(c) }
151
+
152
+ able_columns = collection_columns.select {|v| v.match('able') }
153
+ collection_columns.delete_if {|c| able_columns.include?(c) }
154
+
155
+ is_columns = collection_columns.select {|v| v.match('is_') }
156
+ collection_columns.delete_if {|c| is_columns.include?(c) }
157
+
158
+ id_columns = collection_columns.select {|v| v.match('_id') || v.match('_type') }
159
+ collection_columns.delete_if {|c| id_columns.include?(c) }
160
+
161
+ at_columns = collection_columns.select {|v| v.match('_at') }
162
+ collection_columns.delete_if {|c| at_columns.include?(c) }
163
+
164
+ last_columns = []
165
+ last_columns.delete_if {|c| !collection_columns.include?(c) }
166
+ collection_columns.delete_if {|c| last_columns.include?(c) }
167
+
168
+ standard_rails_timestamps = ['created_at', 'updated_at']
169
+ standard_rails_timestamps.delete_if {|c| !at_columns.include?(c) }
170
+ at_columns.delete_if {|c| at_columns.include?(c) }
171
+
172
+ content_for :columns_order, "first_columns + collection_columns + bool_columns + able_columns + is_columns + id_columns + at_columns + last_columns + standard_rails_timestamps" unless content_for?(:columns_order)
173
+
174
+ first_columns + collection_columns + bool_columns + able_columns + is_columns + id_columns + at_columns + last_columns + standard_rails_timestamps
175
+ end
176
+
177
+ def resource_cell(row, column)
178
+ if row.is_a?(Hash)
179
+ return "" unless row.has_key?(column)
180
+
181
+ content = row[column].to_s
182
+ else
183
+ return "" unless row.respond_to?(column)
184
+
185
+ content = row.send(column).to_s
186
+ end
187
+
188
+ truncate_length = params['truncate_length'] ? params['truncate_length'].to_i : 50
189
+
190
+ content = content_tag(:span, truncate(raw(content), :length => truncate_length), :title => content) if content.length > truncate_length
191
+
192
+ content
193
+ end
194
+ end