csv_rails 0.6.1 → 0.7.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 +7 -0
- data/README.rdoc +64 -3
- data/lib/csv_rails.rb +1 -0
- data/lib/csv_rails/active_model.rb +6 -1
- data/lib/csv_rails/import.rb +78 -0
- data/lib/csv_rails/version.rb +1 -1
- data/test/csv_rails/active_record_test.rb +2 -1
- data/test/csv_rails/array_test.rb +2 -2
- data/test/csv_rails/import_test.rb +134 -0
- data/test/dummy/app/controllers/groups_controller.rb +17 -0
- data/test/dummy/app/controllers/users_controller.rb +1 -1
- data/test/dummy/app/helpers/groups_helper.rb +2 -0
- data/test/dummy/app/models/group.rb +1 -0
- data/test/dummy/app/models/user.rb +2 -0
- data/test/dummy/config/database.yml +7 -19
- data/test/dummy/config/environments/test.rb +6 -0
- data/test/dummy/config/initializers/secret_token.rb +6 -1
- data/test/dummy/config/locales/ja.yml +4 -1
- data/test/dummy/config/mongoid.yml +66 -5
- data/test/dummy/config/routes.rb +1 -0
- data/test/dummy/coverage/assets/0.7.1/application.css +1110 -0
- data/test/dummy/coverage/assets/0.7.1/application.js +626 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/loading.gif +0 -0
- data/test/dummy/coverage/assets/0.7.1/magnify.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/test/dummy/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/test/dummy/coverage/index.html +72 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +108 -1682
- data/test/dummy/log/test.log +46674 -58091
- data/test/dummy/test/fixtures/groups.csv +5 -0
- data/test/dummy/test/fixtures/groups_includes_wrong_user_name.csv +3 -0
- data/test/dummy/test/functional/groups_controller_test.rb +35 -0
- data/test/dummy/test/functional/users_controller_test.rb +3 -3
- data/test/dummy/test/unit/helpers/groups_helper_test.rb +4 -0
- data/test/test_helper.rb +1 -1
- metadata +206 -126
- data/test/dummy/doc/README_FOR_APP +0 -2
- data/test/dummy/log/production.log +0 -0
- data/test/dummy/log/server.log +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: abca01f38995c646411bf71c5194c44761f581ab
|
|
4
|
+
data.tar.gz: 0802df4b50d7487420c7f642154834a087675b98
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 16d5d26847e86645c93d3a5f16885a91409c4a6e14a5b6360908510a0e607771f94cdfde8632d16eb297cebd1e78a9364ab78279c26b1d273d2019a77783350a
|
|
7
|
+
data.tar.gz: 6de4e32ec224e341b2f867ffe45d9c798e69654bf78e741925f7515f2f0ac401c9dc75ed7b23f78267f09a35d939cc1fdcce8a30a12bab9822032cd9da2d9ef9
|
data/README.rdoc
CHANGED
|
@@ -33,6 +33,8 @@ to your Gemfile and then run
|
|
|
33
33
|
|
|
34
34
|
== Usage
|
|
35
35
|
|
|
36
|
+
=== Download
|
|
37
|
+
|
|
36
38
|
If you want formatted attribute, CsvRails call "#{attribute}_as_csv". For example, you wish formatted created_at then you write like this.
|
|
37
39
|
|
|
38
40
|
class User < ActiveRecord::Base
|
|
@@ -77,11 +79,13 @@ If you do not use :header option, header is using :fields and I18n transfer.
|
|
|
77
79
|
groups:
|
|
78
80
|
first:
|
|
79
81
|
<<: *groupmodel
|
|
80
|
-
#
|
|
82
|
+
# rails 3.2.3 - 3.2.5
|
|
81
83
|
user/groups:
|
|
82
84
|
first:
|
|
83
85
|
<<: *groupmodel
|
|
84
|
-
|
|
86
|
+
# rails 3.2.6 or higher
|
|
87
|
+
groups/first:
|
|
88
|
+
<<: *groupmodel
|
|
85
89
|
|
|
86
90
|
# app/controllers/user_controller.rb
|
|
87
91
|
def index
|
|
@@ -110,4 +114,61 @@ You also use i18n_scope option
|
|
|
110
114
|
|
|
111
115
|
User.where("id < 1").all.to_csv(:i18n_scope => :csv) #=> "なまえ\n"
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
=== Upload
|
|
118
|
+
|
|
119
|
+
CSVRails is also have upload concern.
|
|
120
|
+
|
|
121
|
+
You should include CSVRails::Import into your model.
|
|
122
|
+
|
|
123
|
+
example
|
|
124
|
+
|
|
125
|
+
# app/model/user.rb
|
|
126
|
+
class User < ActiveRecord::Base
|
|
127
|
+
attr_accessor :file
|
|
128
|
+
include CsvRails::Import
|
|
129
|
+
....
|
|
130
|
+
|
|
131
|
+
And render file_field into form
|
|
132
|
+
|
|
133
|
+
example
|
|
134
|
+
|
|
135
|
+
# app/views/users/index.html.erb
|
|
136
|
+
|
|
137
|
+
<%= form_for(@user, multipart: true) do |f| %>
|
|
138
|
+
File: <%= f.file_field :file %>
|
|
139
|
+
<%= f.submit 'Upload' %>
|
|
140
|
+
<% end %>
|
|
141
|
+
|
|
142
|
+
Next implement action
|
|
143
|
+
|
|
144
|
+
# app/controllers/users_controller.rb
|
|
145
|
+
|
|
146
|
+
def create
|
|
147
|
+
if params[:format] == 'csv'
|
|
148
|
+
users = User.csv_import(params[:file])
|
|
149
|
+
if users.find{|u| u.errors.any? }
|
|
150
|
+
render :index
|
|
151
|
+
else
|
|
152
|
+
redirect_to users_path, notice: 'Upload success'
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
csv_import is be able to use block.
|
|
158
|
+
|
|
159
|
+
User.csv_import(params[:file]) do |user, params, row_number|
|
|
160
|
+
next false if row_number == 2 # 'next false' in the block, the line is skipped.
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
csv_import use transaction, if invalid line is existed then all rows is not imported.
|
|
164
|
+
|
|
165
|
+
First line used for fields, but you can manually choose it using options
|
|
166
|
+
|
|
167
|
+
User.csv_import(params[:file], fields: [:age, :name])
|
|
168
|
+
|
|
169
|
+
It line first line has 'id', csv_import call where(id: id).first_or_initialize, but you can use other field name
|
|
170
|
+
|
|
171
|
+
User.csv_import(params[:file], find_key: :name)
|
|
172
|
+
#=> It call User.where(name: name).first_or_initialize internal.
|
|
173
|
+
|
|
174
|
+
Copyright (c) 2012-2013 yalab, released under the MIT license
|
data/lib/csv_rails.rb
CHANGED
|
@@ -5,7 +5,12 @@ module CsvRails
|
|
|
5
5
|
def to_csv(opts={})
|
|
6
6
|
fields = opts[:fields] || csv_fields
|
|
7
7
|
header = csv_header(fields, opts.delete(:i18n_scope))
|
|
8
|
-
all
|
|
8
|
+
all = if self.respond_to?(:to_a)
|
|
9
|
+
to_a
|
|
10
|
+
else
|
|
11
|
+
send(:all).to_a
|
|
12
|
+
end
|
|
13
|
+
all.to_csv(opts.update(:fields => fields, :header => header))
|
|
9
14
|
end
|
|
10
15
|
|
|
11
16
|
def csv_header(fields, scope=nil)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
module CsvRails::Import
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
module ClassMethods
|
|
5
|
+
def inverse_human_attriute_name(attribute, options = {})
|
|
6
|
+
defaults = options[:defaults] || []
|
|
7
|
+
parts = attribute.to_s.split(".")
|
|
8
|
+
attribute = parts.pop
|
|
9
|
+
namespace = parts.join("/") unless parts.empty?
|
|
10
|
+
|
|
11
|
+
if defaults.blank?
|
|
12
|
+
if namespace
|
|
13
|
+
lookup_ancestors.each do |klass|
|
|
14
|
+
defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}/#{namespace}"
|
|
15
|
+
end
|
|
16
|
+
defaults << :"#{self.i18n_scope}.attributes.#{namespace}"
|
|
17
|
+
else
|
|
18
|
+
lookup_ancestors.each do |klass|
|
|
19
|
+
defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
defaults << :"attributes"
|
|
23
|
+
end
|
|
24
|
+
entry = nil
|
|
25
|
+
defaults.each do |k|
|
|
26
|
+
map = I18n.translate(k)
|
|
27
|
+
if map.is_a?(Hash)
|
|
28
|
+
entry = map.invert[attribute]
|
|
29
|
+
break
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
entry || attribute.underscore.gsub(/ /, '_')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def csv_import(body, opts={})
|
|
36
|
+
fields = opts.delete(:fields)
|
|
37
|
+
find_key = opts.has_key?(:find_key) ? opts.delete(:find_key) : :id
|
|
38
|
+
records = []
|
|
39
|
+
all_green = true
|
|
40
|
+
translated = false
|
|
41
|
+
self.transaction do
|
|
42
|
+
CSV.parse(body, opts).each.with_index do |row, i|
|
|
43
|
+
unless fields
|
|
44
|
+
fields = row
|
|
45
|
+
next
|
|
46
|
+
end
|
|
47
|
+
unless translated
|
|
48
|
+
fields.map!{|f| inverse_human_attriute_name(f) }
|
|
49
|
+
translated = true
|
|
50
|
+
end
|
|
51
|
+
attributes = ActiveSupport::HashWithIndifferentAccess.new(Hash[fields.zip(row)])
|
|
52
|
+
record = if find_key
|
|
53
|
+
self.where(:"#{find_key}" => attributes[find_key.to_s]).first_or_initialize
|
|
54
|
+
else
|
|
55
|
+
self.new
|
|
56
|
+
end
|
|
57
|
+
record.attributes = attributes.select{|k, v| self.attribute_method?(k) }
|
|
58
|
+
if block_given?
|
|
59
|
+
val = yield record, attributes, i
|
|
60
|
+
next if val == false
|
|
61
|
+
end
|
|
62
|
+
if all_green && record.valid?
|
|
63
|
+
record.save!
|
|
64
|
+
else
|
|
65
|
+
all_green = false
|
|
66
|
+
end
|
|
67
|
+
records << record
|
|
68
|
+
end
|
|
69
|
+
raise ActiveRecord::Rollback unless all_green
|
|
70
|
+
end
|
|
71
|
+
records
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def tsv_import(body, opts={}, &block)
|
|
75
|
+
csv_import(body, opts.merge(col_sep: "\t"), &block)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/csv_rails/version.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
require 'test_helper'
|
|
3
3
|
class CsvRails::ActiveRecordTest < ActiveSupport::TestCase
|
|
4
4
|
setup do
|
|
5
|
+
I18n.locale = :en
|
|
5
6
|
@user = User.create(:name => 'yalab', :age => '29', :secret => 'password')
|
|
6
7
|
@group = Group.create(:name => 'ruby')
|
|
7
8
|
@user.groups << @group
|
|
@@ -95,6 +96,6 @@ class CsvRails::ActiveRecordTest < ActiveSupport::TestCase
|
|
|
95
96
|
end
|
|
96
97
|
|
|
97
98
|
test ".to_csv with row_sep option" do
|
|
98
|
-
assert_match /\r\n/, User.all.to_csv(:row_sep => "\r\n")
|
|
99
|
+
assert_match /\r\n/, User.all.to_a.to_csv(:row_sep => "\r\n")
|
|
99
100
|
end
|
|
100
101
|
end
|
|
@@ -53,12 +53,12 @@ class CsvRails::ArrayTest < ActiveSupport::TestCase
|
|
|
53
53
|
test ".to_csv only it includes Mongoid instance" do
|
|
54
54
|
post = Post.create(:title => 'this is csv_rails', :body => "line\nline\nline\n")
|
|
55
55
|
|
|
56
|
-
assert_equal "
|
|
56
|
+
assert_equal "\"\",タイトル,本文\n#{post._id},#{post.title},\"#{post.body}\"\n", [post].to_csv
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
test ".to_tsv only it includes Mongoid instance" do
|
|
60
60
|
post = Post.create(:title => 'this is csv_rails', :body => "line\nline\nline\n")
|
|
61
61
|
|
|
62
|
-
assert_equal "
|
|
62
|
+
assert_equal "\"\"\tタイトル\t本文\n#{post._id}\t#{post.title}\t\"#{post.body}\"\n", [post].to_tsv
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
class CsvRails::ImportTest < ActiveSupport::TestCase
|
|
5
|
+
setup do
|
|
6
|
+
I18n.locale = :en
|
|
7
|
+
@users = [{id: 1, name: 'yoshida', age: 30, secret: 'password'},
|
|
8
|
+
{id: 2, name: 'yalab', age: 3, secret: 'password'}]
|
|
9
|
+
csv = <<-EOS.gsub(/^\s+/, '')
|
|
10
|
+
id,name,age,secret
|
|
11
|
+
#{@users[0].values.join(',')}
|
|
12
|
+
#{@users[1].values.join(',')}
|
|
13
|
+
EOS
|
|
14
|
+
@csv = StringIO.new(csv)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "import IO" do
|
|
18
|
+
User.csv_import(@csv)
|
|
19
|
+
@users.each do |params|
|
|
20
|
+
user = User.find(params[:id])
|
|
21
|
+
params.each do |k, v|
|
|
22
|
+
assert_equal v, user[k]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test "import with block" do
|
|
28
|
+
name = 'test'
|
|
29
|
+
User.csv_import(@csv) do |user, params|
|
|
30
|
+
if params[:id] == '1'
|
|
31
|
+
user.name = name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
user = User.find(1)
|
|
35
|
+
assert_equal name, user.name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "import with fields option" do
|
|
39
|
+
user = {name: 'atsushi', age: 14}
|
|
40
|
+
csv = <<-EOS.gsub(/^\s*/, '')
|
|
41
|
+
#{user.values.join(',')}
|
|
42
|
+
EOS
|
|
43
|
+
users = User.csv_import(StringIO.new(csv), fields: user.keys)
|
|
44
|
+
user.each do |k, v|
|
|
45
|
+
assert_equal v, users.first[k]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "import skip blank line" do
|
|
50
|
+
csv = <<-EOS.gsub(/^\s*/, '')
|
|
51
|
+
name,age
|
|
52
|
+
|
|
53
|
+
yoshida,30
|
|
54
|
+
EOS
|
|
55
|
+
User.csv_import(csv)
|
|
56
|
+
assert_equal 1, User.count
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "import skip if block returns false" do
|
|
60
|
+
User.csv_import(@csv) do |user|
|
|
61
|
+
next false if user.id == 2
|
|
62
|
+
end
|
|
63
|
+
assert_nil User.find_by_id(2)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test "import is transaction" do
|
|
67
|
+
User.csv_import(@csv) do |user, attributes, index|
|
|
68
|
+
raise ActiveRecord::Rollback if index == 2
|
|
69
|
+
end
|
|
70
|
+
assert_nil User.find_by_id(1)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
test "includes invalid attributes" do
|
|
74
|
+
csv =<<-EOS.gsub(/^\s*/, '')
|
|
75
|
+
name,age
|
|
76
|
+
,30
|
|
77
|
+
yoshida,12
|
|
78
|
+
EOS
|
|
79
|
+
users = User.csv_import(csv)
|
|
80
|
+
assert_equal 0, User.count
|
|
81
|
+
assert_equal ["Name can't be blank"], users[0].errors.full_messages
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
test "import can accept not a column" do
|
|
85
|
+
csv =<<-EOS.gsub(/^\s*/, '')
|
|
86
|
+
name,age,group_name
|
|
87
|
+
yoshida,12,human
|
|
88
|
+
EOS
|
|
89
|
+
assert_difference("User.count") do
|
|
90
|
+
User.csv_import(csv) do |user, attributes|
|
|
91
|
+
assert_equal 'human', attributes[:group_name]
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "it also use tsv_import" do
|
|
97
|
+
secret = 'hogehoge'
|
|
98
|
+
User.tsv_import(@csv.read.gsub(/,/, "\t")) do |user, params, ix|
|
|
99
|
+
user.secret = secret if user.name == 'yalab'
|
|
100
|
+
end
|
|
101
|
+
@users.each do |params|
|
|
102
|
+
user = User.find_by_id(params[:id])
|
|
103
|
+
params.each do |k, v|
|
|
104
|
+
if k == :secret && user.name == 'yalab'
|
|
105
|
+
v = secret
|
|
106
|
+
end
|
|
107
|
+
assert_equal v, user[k]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
test "inverse_human_attriute_name" do
|
|
113
|
+
I18n.locale = :ja
|
|
114
|
+
assert_equal :name, User.inverse_human_attriute_name("名前")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test "csv download upload" do
|
|
118
|
+
I18n.locale = :ja
|
|
119
|
+
user = User.create(name: 'foobar', age: 20)
|
|
120
|
+
User.csv_import(User.to_csv.gsub('foobar', 'hogehoge'))
|
|
121
|
+
assert_equal 'hogehoge', user.reload.name
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
test "import can choose key" do
|
|
125
|
+
csv =<<-EOS.gsub(/^\s*/, '')
|
|
126
|
+
name,age,group_name
|
|
127
|
+
yoshida,12,human
|
|
128
|
+
yoshida,15,human
|
|
129
|
+
EOS
|
|
130
|
+
User.csv_import(csv, find_key: :name)
|
|
131
|
+
assert_equal 1, User.count
|
|
132
|
+
assert_equal 15, User.find(1).age
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class GroupsController < ApplicationController
|
|
2
|
+
def create
|
|
3
|
+
user_prefix = /^user_/
|
|
4
|
+
@groups = Group.csv_import(params[:group][:file], find_key: :name) do |group, _params, i|
|
|
5
|
+
user_params = _params.select{|k, v| k =~ user_prefix }.to_a.inject({}){|hash, (k, v)|
|
|
6
|
+
hash[k.gsub(user_prefix, '')] = v
|
|
7
|
+
hash
|
|
8
|
+
}
|
|
9
|
+
user_params
|
|
10
|
+
user = User.where(name: user_params['name']).first_or_initialize
|
|
11
|
+
user.attributes = user_params
|
|
12
|
+
group.users << user
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
render text: nil
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -9,7 +9,7 @@ class UsersController < ApplicationController
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def sjis
|
|
12
|
-
@users = User.includes(:groups).
|
|
12
|
+
@users = User.includes(:groups).to_a
|
|
13
13
|
respond_to do |format|
|
|
14
14
|
format.html
|
|
15
15
|
format.csv { render csv: @users, fields: [:id, :name, :age, :"groups.first.name"], encoding: 'SJIS' }
|
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
# gem install sqlite3
|
|
3
|
-
#
|
|
4
|
-
# Ensure the SQLite 3 gem is defined in your Gemfile
|
|
5
|
-
# gem 'sqlite3'
|
|
6
|
-
development:
|
|
1
|
+
default: &default
|
|
7
2
|
adapter: sqlite3
|
|
8
|
-
database: db/development.sqlite3
|
|
9
3
|
pool: 5
|
|
10
4
|
timeout: 5000
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
development:
|
|
7
|
+
<<: *default
|
|
8
|
+
database: db/development.sqlite3
|
|
9
|
+
|
|
15
10
|
test:
|
|
16
|
-
|
|
17
|
-
database:
|
|
18
|
-
pool: 5
|
|
19
|
-
timeout: 5000
|
|
11
|
+
<<: *default
|
|
12
|
+
database: ":memory:"
|
|
20
13
|
|
|
21
|
-
production:
|
|
22
|
-
adapter: sqlite3
|
|
23
|
-
database: db/production.sqlite3
|
|
24
|
-
pool: 5
|
|
25
|
-
timeout: 5000
|