rails_info 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +58 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/rails_info/application.js +6 -0
- data/app/assets/javascripts/rails_info/base.js.coffee +6 -0
- data/app/assets/javascripts/rails_info/bootstrap.js.coffee +4 -0
- data/app/assets/stylesheets/rails_info/application.css +14 -0
- data/app/assets/stylesheets/rails_info/base.css.scss +22 -0
- data/app/assets/stylesheets/rails_info/bootstrap_and_overrides.css.less +63 -0
- data/app/assets/stylesheets/rails_info/exception.css +17 -0
- data/app/assets/stylesheets/rails_info/exception/base.css.scss +31 -0
- data/app/assets/stylesheets/rails_info/exception/pygments.css.erb +5 -0
- data/app/controllers/rails_info/data_controller.rb +9 -0
- data/app/controllers/rails_info/logs/server_controller.rb +10 -0
- data/app/controllers/rails_info/logs/test/rspec_controller.rb +16 -0
- data/app/controllers/rails_info/model_controller.rb +5 -0
- data/app/controllers/rails_info/properties_controller.rb +4 -0
- data/app/controllers/rails_info/routes_controller.rb +4 -0
- data/app/controllers/rails_info/stack_traces_controller.rb +11 -0
- data/app/controllers/rails_info_controller.rb +16 -0
- data/app/helpers/rails_info/resources_helper.rb +194 -0
- data/app/presenters/rails_info/code_presenter.rb +63 -0
- data/app/presenters/rails_info/data/object_presenter.rb +34 -0
- data/app/presenters/rails_info/data/row_set_presenter.rb +38 -0
- data/app/presenters/rails_info/data_presenter.rb +21 -0
- data/app/presenters/rails_info/logs/server/action_presenter.rb +109 -0
- data/app/presenters/rails_info/logs/server_presenter.rb +57 -0
- data/app/presenters/rails_info/logs/test/rspec/file_presenter.rb +87 -0
- data/app/presenters/rails_info/logs/test/rspec_presenter.rb +32 -0
- data/app/presenters/rails_info/model_presenter.rb +68 -0
- data/app/presenters/rails_info/presenter.rb +19 -0
- data/app/presenters/rails_info/stack_trace_presenter.rb +98 -0
- data/app/views/layouts/_layout.html.erb +19 -0
- data/app/views/layouts/rails_info.html.erb +1 -0
- data/app/views/layouts/rails_info/exception.html.erb +1 -0
- data/app/views/layouts/shared/_navigation.html.erb +7 -0
- data/app/views/rails_info/data/index.html.erb +23 -0
- data/app/views/rails_info/logs/server/_table.html.erb +16 -0
- data/app/views/rails_info/logs/server/new.html.erb +19 -0
- data/app/views/rails_info/logs/test/rspec/new.html.erb +10 -0
- data/app/views/rails_info/model/index.html.erb +14 -0
- data/app/views/rails_info/properties/index.html.erb +1 -0
- data/app/views/rails_info/routes/index.html.erb +18 -0
- data/app/views/rails_info/stack_traces/_accordion.html.erb +1 -0
- data/app/views/rails_info/stack_traces/_form.html.erb +11 -0
- data/app/views/rails_info/stack_traces/_with_request_and_response.html.erb +16 -0
- data/app/views/rails_info/stack_traces/new.html.erb +10 -0
- data/config/navigation.rb +20 -0
- data/config/routes.rb +20 -0
- data/lib/rails_info.rb +19 -0
- data/lib/rails_info/controller.rb +2 -0
- data/lib/rails_info/controller/exception_diagnostics.rb +28 -0
- data/lib/rails_info/data.rb +55 -0
- data/lib/rails_info/engine.rb +9 -0
- data/lib/rails_info/logs.rb +2 -0
- data/lib/rails_info/logs/server.rb +230 -0
- data/lib/rails_info/logs/test.rb +2 -0
- data/lib/rails_info/logs/test/rspec.rb +160 -0
- data/lib/rails_info/model.rb +221 -0
- data/lib/rails_info/stack_trace.rb +155 -0
- data/lib/rails_info/version.rb +3 -0
- data/lib/tasks/rails_info_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +59 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +42 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +39 -0
- data/spec/dummy/config/environments/production.rb +69 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/log/development.log +4876 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- metadata +274 -0
data/MIT-LICENSE
ADDED
@@ -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.
|
data/README.rdoc
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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,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,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,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
|