collection2csv 0.1.4 → 1.0.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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +35 -3
- data/.rspec +1 -0
- data/.rubocop.yml +40 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +9 -2
- data/README.md +38 -15
- data/Rakefile +6 -2
- data/UPGRADE_GUIDE.md +24 -0
- data/app/controllers/collection2csv_controller.rb +7 -23
- data/app/helpers/collection_to_csv_helper.rb +12 -4
- data/collection2csv.gemspec +30 -18
- data/config/routes.rb +3 -2
- data/lib/collection2csv/convertor.rb +103 -0
- data/lib/collection2csv/version.rb +3 -1
- data/lib/collection2csv.rb +6 -7
- metadata +116 -18
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: aba616840f6db9d424f9925ff60f8b6aa3b4f2dee4d9aeac23d6f8e6e47a50f6
|
|
4
|
+
data.tar.gz: 5af63fcfa375958eb6a19b9fe7176bac136281024093e7bc40086a7344f0d45c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0cffcd5b59cc9a0ea4cf50be3cdc1097201c297fe80ea739982ac2770a212593ed8cbac588f745ac48ac9a3e65ddbb8c0bb3d4a1d3925097d716a69b6ffa7f16
|
|
7
|
+
data.tar.gz: 8713793bd6cb33dc4d10491c30b246545dbc35774115299498f186f3aa1b0bfa8cf38d7f84d099d3447ac7b176694bc6e10b891a7092d2c1b5c0d4026edf73a1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master, modernize ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master, modernize ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
ruby: ['3.0', '3.1', '3.2', '3.3']
|
|
16
|
+
rails: ['6.0', '6.1', '7.0', '7.1', '7.2', '8.0']
|
|
17
|
+
exclude:
|
|
18
|
+
- ruby: '3.0'
|
|
19
|
+
rails: '7.2'
|
|
20
|
+
- ruby: '3.0'
|
|
21
|
+
rails: '8.0'
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Set up Ruby
|
|
30
|
+
uses: ruby/setup-ruby@v1
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: ${{ matrix.ruby }}
|
|
33
|
+
bundler-cache: true
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: bundle exec rake
|
|
37
|
+
|
|
38
|
+
- name: Run RuboCop
|
|
39
|
+
run: bundle exec rubocop
|
|
40
|
+
|
|
41
|
+
security:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Set up Ruby
|
|
48
|
+
uses: ruby/setup-ruby@v1
|
|
49
|
+
with:
|
|
50
|
+
ruby-version: '3.3'
|
|
51
|
+
bundler-cache: true
|
|
52
|
+
|
|
53
|
+
- name: Security audit
|
|
54
|
+
run: bundle exec bundle-audit --update
|
data/.gitignore
CHANGED
|
@@ -1,9 +1,41 @@
|
|
|
1
|
+
## Ruby/Bundler
|
|
1
2
|
/.bundle/
|
|
2
|
-
|
|
3
|
+
/vendor/bundle/
|
|
3
4
|
/Gemfile.lock
|
|
5
|
+
|
|
6
|
+
## Documentation
|
|
7
|
+
/.yardoc/
|
|
4
8
|
/_yardoc/
|
|
5
|
-
/coverage/
|
|
6
9
|
/doc/
|
|
7
|
-
/
|
|
10
|
+
/rdoc/
|
|
11
|
+
|
|
12
|
+
## Testing
|
|
13
|
+
/coverage/
|
|
8
14
|
/spec/reports/
|
|
15
|
+
/test/tmp/
|
|
16
|
+
/test/version_tmp/
|
|
17
|
+
/spec/dummy_app/log/
|
|
18
|
+
/spec/dummy_app/tmp/
|
|
19
|
+
/spec/dummy_app/db/*.sqlite3
|
|
20
|
+
|
|
21
|
+
## Build artifacts
|
|
22
|
+
/pkg/
|
|
9
23
|
/tmp/
|
|
24
|
+
*.gem
|
|
25
|
+
|
|
26
|
+
## IDE and OS files
|
|
27
|
+
.DS_Store
|
|
28
|
+
.idea/
|
|
29
|
+
.vscode/
|
|
30
|
+
*.swp
|
|
31
|
+
*.swo
|
|
32
|
+
*~
|
|
33
|
+
.ruby-version
|
|
34
|
+
.ruby-gemset
|
|
35
|
+
|
|
36
|
+
## Environment
|
|
37
|
+
.env
|
|
38
|
+
.env.local
|
|
39
|
+
|
|
40
|
+
## Logs
|
|
41
|
+
npm-debug.log
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--require rails_helper
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 3.0
|
|
3
|
+
NewCops: enable
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
Exclude:
|
|
6
|
+
- 'vendor/**/*'
|
|
7
|
+
- 'bin/**/*'
|
|
8
|
+
- 'spec/dummy_app/**/*'
|
|
9
|
+
|
|
10
|
+
Style/Documentation:
|
|
11
|
+
Enabled: false
|
|
12
|
+
|
|
13
|
+
Style/StringLiterals:
|
|
14
|
+
Enabled: true
|
|
15
|
+
EnforcedStyle: double_quotes
|
|
16
|
+
|
|
17
|
+
Style/FrozenStringLiteralComment:
|
|
18
|
+
Enabled: true
|
|
19
|
+
EnforcedStyle: always
|
|
20
|
+
|
|
21
|
+
Layout/LineLength:
|
|
22
|
+
Max: 120
|
|
23
|
+
Exclude:
|
|
24
|
+
- '*.gemspec'
|
|
25
|
+
- 'spec/**/*'
|
|
26
|
+
|
|
27
|
+
Metrics/BlockLength:
|
|
28
|
+
Exclude:
|
|
29
|
+
- 'spec/**/*'
|
|
30
|
+
- '*.gemspec'
|
|
31
|
+
|
|
32
|
+
Gemspec/DevelopmentDependencies:
|
|
33
|
+
Enabled: false
|
|
34
|
+
|
|
35
|
+
Gemspec/AddRuntimeDependency:
|
|
36
|
+
Enabled: false
|
|
37
|
+
|
|
38
|
+
Naming/AccessorMethodName:
|
|
39
|
+
Exclude:
|
|
40
|
+
- 'lib/collection2csv/convertor.rb'
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-05-30
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Minimum Ruby version increased to 3.0
|
|
10
|
+
- Minimum Rails version increased to 6.0
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Explicit `railties` runtime dependency (>= 6.0, < 9.0)
|
|
15
|
+
- GitHub Actions CI with Ruby and Rails matrix
|
|
16
|
+
- RuboCop configuration and linting in CI
|
|
17
|
+
- bundler-audit security scanning in CI
|
|
18
|
+
- CHANGELOG and UPGRADE_GUIDE
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Modernized gemspec and development dependencies
|
|
23
|
+
- Replaced Appraisal/Travis CI with GitHub Actions matrix
|
|
24
|
+
- Updated dummy app and specs for Rails 6+
|
|
25
|
+
- Updated README with Requirements section
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
- Appraisal gemfiles for Rails 4.x and 5.0
|
|
30
|
+
- Travis CI configuration
|
|
31
|
+
|
|
32
|
+
## [0.1.5] - Previous Release
|
|
33
|
+
|
|
34
|
+
- ActiveRecord collection CSV export helper and controller
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
For upgrade instructions, see [UPGRADE_GUIDE.md](UPGRADE_GUIDE.md)
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
2
4
|
|
|
3
|
-
# Specify your gem's dependencies in collection2csv.gemspec
|
|
4
5
|
gemspec
|
|
6
|
+
|
|
7
|
+
if (rails_version = ENV.fetch("RAILS_VERSION", nil))
|
|
8
|
+
gem "rails", "~> #{rails_version}.0"
|
|
9
|
+
else
|
|
10
|
+
gem "rails", "~> 7.1.0"
|
|
11
|
+
end
|
data/README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# Collection2csv
|
|
2
2
|
|
|
3
|
-
[](https://hakiri.io/github/ethirajsrinivasan/collection2csv/master)
|
|
3
|
+
[](https://github.com/ethirajsrinivasan/collection2csv/actions/workflows/ci.yml)
|
|
4
|
+
[](https://badge.fury.io/rb/collection2csv)
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
Export ActiveRecord collections to CSV via a Rails helper and download endpoint.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Ruby >= 3.0
|
|
11
|
+
- Rails >= 6.0
|
|
8
12
|
|
|
9
13
|
## Installation
|
|
10
14
|
|
|
@@ -16,31 +20,50 @@ gem 'collection2csv'
|
|
|
16
20
|
|
|
17
21
|
And then execute:
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
```bash
|
|
24
|
+
bundle install
|
|
25
|
+
```
|
|
20
26
|
|
|
21
27
|
Or install it yourself as:
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
```bash
|
|
30
|
+
gem install collection2csv
|
|
31
|
+
```
|
|
24
32
|
|
|
25
33
|
## Usage
|
|
26
34
|
|
|
27
|
-
Use the collection_download helper
|
|
35
|
+
Use the `collection_download` helper:
|
|
36
|
+
|
|
37
|
+
```erb
|
|
38
|
+
<%= collection_download(@users) %>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Select specific columns:
|
|
28
42
|
|
|
29
|
-
|
|
43
|
+
```erb
|
|
44
|
+
<%= collection_download(@users, columns: ['id', 'name']) %>
|
|
45
|
+
```
|
|
30
46
|
|
|
31
|
-
|
|
47
|
+
Custom link text:
|
|
32
48
|
|
|
33
|
-
|
|
49
|
+
```erb
|
|
50
|
+
<%= collection_download(@users, link_text: 'Download CSV') %>
|
|
51
|
+
```
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
Include associations:
|
|
36
54
|
|
|
55
|
+
```erb
|
|
56
|
+
<%= collection_download(@users, associations: { book: ['id', 'name'] }) %>
|
|
57
|
+
```
|
|
37
58
|
|
|
38
|
-
##
|
|
59
|
+
## Upgrading from 0.x to 1.0
|
|
39
60
|
|
|
40
|
-
|
|
61
|
+
Version 1.0.0 requires Ruby 3.0+ and Rails 6.0+. See [UPGRADE_GUIDE.md](UPGRADE_GUIDE.md).
|
|
41
62
|
|
|
63
|
+
## Contributing
|
|
42
64
|
|
|
43
|
-
|
|
65
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ethirajsrinivasan/collection2csv. Contributors are expected to adhere to the [Contributor Covenant](CODE_OF_CONDUCT.md) code of conduct.
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
## License
|
|
46
68
|
|
|
69
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/Rakefile
CHANGED
data/UPGRADE_GUIDE.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Upgrade Guide: Collection2csv 0.x to 1.0
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Collection2csv 1.0 modernizes the gem for current Ruby and Rails versions.
|
|
6
|
+
|
|
7
|
+
## What Changed
|
|
8
|
+
|
|
9
|
+
| Component | Old Version | New Version |
|
|
10
|
+
|-----------|-------------|-------------|
|
|
11
|
+
| Ruby | >= 2.0.0 | >= 3.0 |
|
|
12
|
+
| Rails | >= 4.0 (via Appraisal) | >= 6.0 |
|
|
13
|
+
|
|
14
|
+
## Upgrade Steps
|
|
15
|
+
|
|
16
|
+
1. Ensure your application runs Ruby 3.0+ and Rails 6.0+
|
|
17
|
+
2. Update your Gemfile: `gem 'collection2csv', '~> 1.0'`
|
|
18
|
+
3. Run `bundle update collection2csv`
|
|
19
|
+
4. Verify CSV export links and downloads still work
|
|
20
|
+
|
|
21
|
+
## Getting Help
|
|
22
|
+
|
|
23
|
+
- [GitHub Issues](https://github.com/ethirajsrinivasan/collection2csv/issues)
|
|
24
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
@@ -1,27 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
class Collection2csvController < ApplicationController
|
|
3
|
-
def convert
|
|
4
|
-
klass = params[:klass].constantize
|
|
5
|
-
if params[:column_names].present?
|
|
6
|
-
column_names = params[:column_names].split(',').to_a
|
|
7
|
-
else
|
|
8
|
-
column_names = klass.column_names
|
|
9
|
-
end
|
|
10
|
-
collection = klass.find(params[:ids])
|
|
11
|
-
respond_to do |format|
|
|
12
|
-
format.csv { send_data to_csv(collection,column_names) ,:filename => "#{klass}_#{DateTime.now.to_formatted_s(:db)}.csv"
|
|
13
|
-
}
|
|
14
|
-
end
|
|
15
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
16
2
|
|
|
17
|
-
|
|
3
|
+
require "csv"
|
|
4
|
+
require "collection2csv/convertor"
|
|
18
5
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
csv << product.attributes.values_at(*column_names)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
6
|
+
class Collection2csvController < ApplicationController
|
|
7
|
+
def convert
|
|
8
|
+
send_data Collection2csv::Convertor.new(params).perform,
|
|
9
|
+
filename: "#{params[:klass]}_#{DateTime.now.to_formatted_s(:db)}.csv"
|
|
26
10
|
end
|
|
27
11
|
end
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module CollectionToCsvHelper
|
|
2
|
-
def collection_download(collection,
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
def collection_download(collection, options = {})
|
|
5
|
+
column_names = options[:columns].presence
|
|
6
|
+
associations = options[:associations].presence
|
|
7
|
+
link_text = options[:link_text].presence || "Download"
|
|
8
|
+
klass = collection.try(:first).class
|
|
9
|
+
raise("#{collection} is not a ActiveRecord collection") unless klass.ancestors.include?(ActiveRecord::Base)
|
|
10
|
+
|
|
5
11
|
collection_ids = collection.map(&:id)
|
|
6
|
-
link_to
|
|
12
|
+
link_to link_text,
|
|
13
|
+
collection2csv_path(ids: collection_ids, klass: klass, format: "csv",
|
|
14
|
+
column_names: column_names, associations: associations)
|
|
7
15
|
end
|
|
8
16
|
end
|
data/collection2csv.gemspec
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
require 'collection2csv/version'
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/collection2csv/version"
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
6
|
spec.name = "collection2csv"
|
|
8
7
|
spec.version = Collection2csv::VERSION
|
|
9
|
-
spec.authors = ["
|
|
8
|
+
spec.authors = ["ethi"]
|
|
10
9
|
spec.email = ["ethirajsrinivasan@gmail.com"]
|
|
11
10
|
|
|
12
|
-
spec.summary = "Download ActiveRecord collection as
|
|
13
|
-
spec.description = "
|
|
11
|
+
spec.summary = "Download ActiveRecord collection as CSV"
|
|
12
|
+
spec.description = "A Rails engine gem for exporting ActiveRecord collections to CSV via a helper and controller endpoint"
|
|
14
13
|
spec.homepage = "https://github.com/ethirajsrinivasan/collection2csv"
|
|
15
14
|
spec.license = "MIT"
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
spec.metadata = {
|
|
17
|
+
"allowed_push_host" => "https://rubygems.org",
|
|
18
|
+
"homepage_uri" => spec.homepage,
|
|
19
|
+
"source_code_uri" => "https://github.com/ethirajsrinivasan/collection2csv",
|
|
20
|
+
"bug_tracker_uri" => "https://github.com/ethirajsrinivasan/collection2csv/issues",
|
|
21
|
+
"changelog_uri" => "https://github.com/ethirajsrinivasan/collection2csv/blob/master/CHANGELOG.md",
|
|
22
|
+
"documentation_uri" => "https://github.com/ethirajsrinivasan/collection2csv/blob/master/README.md",
|
|
23
|
+
"rubygems_mfa_required" => "true"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
spec.files = Dir.chdir(__dir__) do
|
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
23
28
|
end
|
|
24
29
|
|
|
25
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
26
30
|
spec.bindir = "exe"
|
|
27
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
32
|
spec.require_paths = ["lib"]
|
|
29
|
-
spec.required_ruby_version = '>= 1.9.3'
|
|
30
|
-
spec.add_development_dependency "bundler", "~> 1.10"
|
|
31
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
|
32
|
-
spec.add_development_dependency "rspec"
|
|
33
33
|
|
|
34
|
+
spec.required_ruby_version = ">= 3.0"
|
|
35
|
+
|
|
36
|
+
spec.add_runtime_dependency "csv"
|
|
37
|
+
spec.add_runtime_dependency "railties", ">= 6.0", "< 9.0"
|
|
38
|
+
|
|
39
|
+
spec.add_development_dependency "bundler", "~> 2.4"
|
|
40
|
+
spec.add_development_dependency "bundler-audit", "~> 0.9"
|
|
41
|
+
spec.add_development_dependency "database_cleaner-active_record"
|
|
42
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
43
|
+
spec.add_development_dependency "rspec-rails", "~> 6.1"
|
|
44
|
+
spec.add_development_dependency "rubocop", "~> 1.50"
|
|
45
|
+
spec.add_development_dependency "sqlite3", ">= 1.4"
|
|
34
46
|
end
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
|
|
5
|
+
module Collection2csv
|
|
6
|
+
class Convertor
|
|
7
|
+
def initialize(params)
|
|
8
|
+
@klass = params[:klass].constantize
|
|
9
|
+
@column_names_from_params = params[:column_names].presence
|
|
10
|
+
@associations_from_params = params[:associations].presence
|
|
11
|
+
@column_names = @column_names_from_params || @klass.column_names
|
|
12
|
+
@associations = @associations_from_params || {}
|
|
13
|
+
@association_class_names = {}
|
|
14
|
+
@association_column_names = []
|
|
15
|
+
@primary_ids = params[:ids]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def perform
|
|
19
|
+
validate
|
|
20
|
+
download
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def validate
|
|
26
|
+
validate_columns if @column_names_from_params.present?
|
|
27
|
+
validate_associations if @associations_from_params.present?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def download
|
|
31
|
+
@collections = @klass.includes(@associations.try(:keys)).find(@primary_ids)
|
|
32
|
+
to_csv(@collections, @column_names, @associations)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def validate_columns
|
|
36
|
+
false_columns = @column_names - @klass.column_names
|
|
37
|
+
raise_error(false_columns, "column", @klass.name) unless false_columns.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def raise_error(false_entities, pluralizer, source = nil)
|
|
41
|
+
msg = construct_error_msg(false_entities, pluralizer)
|
|
42
|
+
msg << " in " if source.present?
|
|
43
|
+
raise msg + source
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def construct_error_msg(false_entities, pluralizer)
|
|
47
|
+
"#{false_entities.join(', ')} #{pluralizer.pluralize(false_entities.count)} not found"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def validate_associations
|
|
51
|
+
return if @associations.empty?
|
|
52
|
+
|
|
53
|
+
get_association_class_names
|
|
54
|
+
validate_association_column_names
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def get_association_class_names
|
|
58
|
+
@klass.reflect_on_all_associations.each do |association|
|
|
59
|
+
@association_class_names[association.name.to_s] =
|
|
60
|
+
association.options[:class_name].presence || association.name.to_s.camelize
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def validate_association_column_names
|
|
65
|
+
@associations.each do |association_key, association_value|
|
|
66
|
+
false_columns = association_value - @association_class_names[association_key.to_s].constantize.column_names
|
|
67
|
+
raise_error(false_columns, "column", association_key) unless false_columns.empty?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def generate_header
|
|
72
|
+
@header = @column_names.map(&:camelize)
|
|
73
|
+
@header += association_column_names
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def association_column_names
|
|
77
|
+
@associations.each do |association_key, association_value|
|
|
78
|
+
association_value.each { |column_name| @association_column_names << "#{association_key}_#{column_name}" }
|
|
79
|
+
end
|
|
80
|
+
@association_column_names.map(&:camelize)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def generate_column_data(collection)
|
|
84
|
+
data = collection.attributes.values_at(*@column_names)
|
|
85
|
+
@associations.empty? ? data : generate_column_data_for_association(collection, data)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def generate_column_data_for_association(collection, data)
|
|
89
|
+
@associations.each do |association_key, association_value|
|
|
90
|
+
obj = collection.public_send(association_key)
|
|
91
|
+
data += obj.present? ? obj.attributes.values_at(*association_value) : Array.new(association_value.count, "")
|
|
92
|
+
end
|
|
93
|
+
data
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def to_csv(_collections, _column_names, _associations)
|
|
97
|
+
CSV.generate do |csv|
|
|
98
|
+
csv << generate_header
|
|
99
|
+
@collections.each { |collection| csv << generate_column_data(collection) }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/lib/collection2csv.rb
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "collection2csv/version"
|
|
4
|
+
require "collection2csv/convertor"
|
|
2
5
|
|
|
3
6
|
module Collection2csv
|
|
4
7
|
class Engine < Rails::Engine
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
end
|
|
9
|
-
|
|
8
|
+
initializer "collection2csv.load_app_instance_data" do |app|
|
|
9
|
+
config.app_root = app.root
|
|
10
|
+
end
|
|
10
11
|
end
|
|
11
12
|
end
|
|
12
|
-
|
|
13
|
-
|
metadata
CHANGED
|
@@ -1,45 +1,78 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: collection2csv
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
autorequire:
|
|
7
|
+
- ethi
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: csv
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: railties
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '6.0'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '9.0'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '6.0'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '9.0'
|
|
13
46
|
- !ruby/object:Gem::Dependency
|
|
14
47
|
name: bundler
|
|
15
48
|
requirement: !ruby/object:Gem::Requirement
|
|
16
49
|
requirements:
|
|
17
50
|
- - "~>"
|
|
18
51
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
52
|
+
version: '2.4'
|
|
20
53
|
type: :development
|
|
21
54
|
prerelease: false
|
|
22
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
56
|
requirements:
|
|
24
57
|
- - "~>"
|
|
25
58
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
59
|
+
version: '2.4'
|
|
27
60
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
61
|
+
name: bundler-audit
|
|
29
62
|
requirement: !ruby/object:Gem::Requirement
|
|
30
63
|
requirements:
|
|
31
64
|
- - "~>"
|
|
32
65
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
66
|
+
version: '0.9'
|
|
34
67
|
type: :development
|
|
35
68
|
prerelease: false
|
|
36
69
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
70
|
requirements:
|
|
38
71
|
- - "~>"
|
|
39
72
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
73
|
+
version: '0.9'
|
|
41
74
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
75
|
+
name: database_cleaner-active_record
|
|
43
76
|
requirement: !ruby/object:Gem::Requirement
|
|
44
77
|
requirements:
|
|
45
78
|
- - ">="
|
|
@@ -52,20 +85,81 @@ dependencies:
|
|
|
52
85
|
- - ">="
|
|
53
86
|
- !ruby/object:Gem::Version
|
|
54
87
|
version: '0'
|
|
55
|
-
|
|
88
|
+
- !ruby/object:Gem::Dependency
|
|
89
|
+
name: rake
|
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '13.0'
|
|
95
|
+
type: :development
|
|
96
|
+
prerelease: false
|
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - "~>"
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '13.0'
|
|
102
|
+
- !ruby/object:Gem::Dependency
|
|
103
|
+
name: rspec-rails
|
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - "~>"
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '6.1'
|
|
109
|
+
type: :development
|
|
110
|
+
prerelease: false
|
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '6.1'
|
|
116
|
+
- !ruby/object:Gem::Dependency
|
|
117
|
+
name: rubocop
|
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - "~>"
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: '1.50'
|
|
123
|
+
type: :development
|
|
124
|
+
prerelease: false
|
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - "~>"
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '1.50'
|
|
130
|
+
- !ruby/object:Gem::Dependency
|
|
131
|
+
name: sqlite3
|
|
132
|
+
requirement: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '1.4'
|
|
137
|
+
type: :development
|
|
138
|
+
prerelease: false
|
|
139
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
140
|
+
requirements:
|
|
141
|
+
- - ">="
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: '1.4'
|
|
144
|
+
description: A Rails engine gem for exporting ActiveRecord collections to CSV via
|
|
145
|
+
a helper and controller endpoint
|
|
56
146
|
email:
|
|
57
147
|
- ethirajsrinivasan@gmail.com
|
|
58
148
|
executables: []
|
|
59
149
|
extensions: []
|
|
60
150
|
extra_rdoc_files: []
|
|
61
151
|
files:
|
|
152
|
+
- ".github/workflows/ci.yml"
|
|
62
153
|
- ".gitignore"
|
|
63
|
-
- ".
|
|
154
|
+
- ".rspec"
|
|
155
|
+
- ".rubocop.yml"
|
|
156
|
+
- CHANGELOG.md
|
|
64
157
|
- CODE_OF_CONDUCT.md
|
|
65
158
|
- Gemfile
|
|
66
159
|
- LICENSE.txt
|
|
67
160
|
- README.md
|
|
68
161
|
- Rakefile
|
|
162
|
+
- UPGRADE_GUIDE.md
|
|
69
163
|
- app/controllers/collection2csv_controller.rb
|
|
70
164
|
- app/helpers/collection_to_csv_helper.rb
|
|
71
165
|
- bin/console
|
|
@@ -73,13 +167,19 @@ files:
|
|
|
73
167
|
- collection2csv.gemspec
|
|
74
168
|
- config/routes.rb
|
|
75
169
|
- lib/collection2csv.rb
|
|
170
|
+
- lib/collection2csv/convertor.rb
|
|
76
171
|
- lib/collection2csv/version.rb
|
|
77
172
|
homepage: https://github.com/ethirajsrinivasan/collection2csv
|
|
78
173
|
licenses:
|
|
79
174
|
- MIT
|
|
80
175
|
metadata:
|
|
81
176
|
allowed_push_host: https://rubygems.org
|
|
82
|
-
|
|
177
|
+
homepage_uri: https://github.com/ethirajsrinivasan/collection2csv
|
|
178
|
+
source_code_uri: https://github.com/ethirajsrinivasan/collection2csv
|
|
179
|
+
bug_tracker_uri: https://github.com/ethirajsrinivasan/collection2csv/issues
|
|
180
|
+
changelog_uri: https://github.com/ethirajsrinivasan/collection2csv/blob/master/CHANGELOG.md
|
|
181
|
+
documentation_uri: https://github.com/ethirajsrinivasan/collection2csv/blob/master/README.md
|
|
182
|
+
rubygems_mfa_required: 'true'
|
|
83
183
|
rdoc_options: []
|
|
84
184
|
require_paths:
|
|
85
185
|
- lib
|
|
@@ -87,16 +187,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
87
187
|
requirements:
|
|
88
188
|
- - ">="
|
|
89
189
|
- !ruby/object:Gem::Version
|
|
90
|
-
version:
|
|
190
|
+
version: '3.0'
|
|
91
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
192
|
requirements:
|
|
93
193
|
- - ">="
|
|
94
194
|
- !ruby/object:Gem::Version
|
|
95
195
|
version: '0'
|
|
96
196
|
requirements: []
|
|
97
|
-
|
|
98
|
-
rubygems_version: 2.4.8
|
|
99
|
-
signing_key:
|
|
197
|
+
rubygems_version: 3.6.7
|
|
100
198
|
specification_version: 4
|
|
101
|
-
summary: Download ActiveRecord collection as
|
|
199
|
+
summary: Download ActiveRecord collection as CSV
|
|
102
200
|
test_files: []
|