activerecord-bixformer 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README-ja.md +246 -167
- data/lib/activerecord-bixformer/model/base.rb +16 -6
- data/lib/activerecord-bixformer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0fefe763e939aad7ff7e50f2961962e24164a4d
|
4
|
+
data.tar.gz: 435fbfa1250fa0f8cb11c6c1b97c678e0a808e02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb7926a45c574069f491893edc80ece85d8a0782976bcb21bbd22d2f0b7b912d87c351bc7335d198c875bfa8576ba2dcb9d4ceab159a6cbda826734e529f0b6d
|
7
|
+
data.tar.gz: f9bfe143d8be2fe6c0101f9703f3fe219ba4cc8cc239a108004a6687f5ba539a8d445644f91b88e6d5c297a8dbc64acd5810534e944116842acf7f53ee17f001
|
data/README-ja.md
CHANGED
@@ -4,10 +4,9 @@
|
|
4
4
|
|
5
5
|
以下のような特徴があります。
|
6
6
|
|
7
|
-
* `accepts_nested_attributes_for`
|
8
|
-
* インポートデータに `primary_key`
|
7
|
+
* `accepts_nested_attributes_for` で定義された関連モデルを同時に扱える
|
8
|
+
* インポートデータに `primary_key` が含まれる場合、それが正当な値かどうかをチェックできる
|
9
9
|
* 設定用クラスを定義して使い、モデル、属性単位で処理をカスタマイズ可能
|
10
|
-
* その設定用クラスを複数定義して、実行時に切り替え可能
|
11
10
|
|
12
11
|
現在のところ、インポート/エクスポート可能なデータ形式は
|
13
12
|
|
@@ -33,18 +32,11 @@ gem 'activerecord-bixformer'
|
|
33
32
|
|
34
33
|
## 構成要素
|
35
34
|
|
36
|
-
|
35
|
+
本フレームワークには以下のような概念を持った構成要素があります。
|
37
36
|
|
38
37
|
### Plan
|
39
38
|
|
40
39
|
インポート/エクスポートの一連の処理をどのように処理するかを定義する設定ファイルの役割です。
|
41
|
-
処理実行時に、複数登録された本クラスのインスタンス群から採用するものを決定するフローになっていて、
|
42
|
-
バージョンや条件による処理内容の切り替えを容易にできます。
|
43
|
-
|
44
|
-
### Runner
|
45
|
-
|
46
|
-
インポート/エクスポートの一連の処理を実行するクラスです。
|
47
|
-
本クラスをそのまま利用するだけでも、インポート/エクスポートが可能です。
|
48
40
|
|
49
41
|
### Model
|
50
42
|
|
@@ -60,206 +52,272 @@ ActiveRecord のモデルの持つ属性に対応して、その属性のイン
|
|
60
52
|
ActiveRecord::Bixformer::Attribute::Base を継承した独自クラスを定義し、
|
61
53
|
Planを適切に定義することで、それを使用して処理内容を切り替えることができます。
|
62
54
|
|
63
|
-
|
64
|
-
|
65
|
-
## 1. Planの実装
|
66
|
-
|
67
|
-
ActiveRecord::Bixformer::Plan::Base を継承して、以下のメソッドを適切に設定して下さい。
|
68
|
-
|
69
|
-
### model_name
|
70
|
-
|
71
|
-
インポート/エクスポート対象のモデル名を返して下さい。
|
72
|
-
例えばusersテーブルのデータが対象であれば、 `:user` です。
|
55
|
+
## 使い方
|
73
56
|
|
74
|
-
###
|
57
|
+
### 1. Planの実装
|
75
58
|
|
76
|
-
|
59
|
+
ActiveRecord::Bixformer::Plan の機能を持ったクラスを以下のように定義して下さい。
|
77
60
|
|
78
61
|
```ruby
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
62
|
+
class SamplePlan
|
63
|
+
include ActiveRecord::Bixformer::Plan
|
64
|
+
|
65
|
+
# [bixformer_for] インポート/エクスポート対象のモデル名の指定
|
66
|
+
#
|
67
|
+
# - 文字列/シンボルで指定
|
68
|
+
#
|
69
|
+
# 例えば、usersテーブルのデータが対象であれば、 user です
|
70
|
+
#
|
71
|
+
bixformer_for :user
|
72
|
+
|
73
|
+
|
74
|
+
# [bixformer_entry] インポート/エクスポート対象の属性/関連モデルと、それらの処理方法の定義
|
75
|
+
#
|
76
|
+
# - ハッシュを返すProcオブジェクトかメソッド名/シンボルで指定
|
77
|
+
# - ここで指定された属性/関連モデルのみが処理対象となる
|
78
|
+
# - キーに指定可能な値は、 type, attributes, associations のいずれか
|
79
|
+
#
|
80
|
+
bixformer_entry -> do
|
81
|
+
{
|
82
|
+
# 対象モデル(上の例なら user )の処理を担当するModelクラス名
|
83
|
+
# 省略可能で、省略された場合は :base が指定される
|
84
|
+
# 指定可能な値については、「本フレームワークに定義されたModel一覧」を参照
|
85
|
+
# または、独自クラスを定義し、 bixformer_load_namespace を設定して
|
86
|
+
type: :base,
|
99
87
|
|
100
|
-
#
|
101
|
-
|
88
|
+
# 処理対象の属性名をキー、その処理を担当するAttributeクラス名を値に持つハッシュ
|
89
|
+
attributes: {
|
90
|
+
|
91
|
+
# 指定可能な値については、「本フレームワークに定義されたAttribute一覧」を参照
|
92
|
+
# または、独自クラスを定義し、 module_load_namespaces を設定
|
93
|
+
name: :base,
|
94
|
+
|
95
|
+
# クラス名を配列にすると、2番目以降の要素は
|
96
|
+
# Attributeインスタンス(この場合は、 ActiveRecord::Bixformer::Attribute::Time )に渡される
|
97
|
+
# 指定可能な値については、「本フレームワークに定義されたAttribute一覧」を参照
|
98
|
+
joined_at: [:time, format: :ymdhms]
|
99
|
+
|
100
|
+
},
|
101
|
+
|
102
|
+
# 処理対象の関連名をキー、その処理を定義したハッシュを値に持つハッシュ
|
103
|
+
associations: {
|
104
|
+
|
105
|
+
# 関連名(例えば、 user.posts で関連レコードが辿れるなら posts )で指定
|
106
|
+
posts: {
|
107
|
+
|
108
|
+
# 関連モデルの定義は、同じように、 type, attributes, associations が定義可能
|
109
|
+
|
110
|
+
# type も、配列にすると、2番目以降の要素は
|
111
|
+
# Modelインスタンス(この場合は、 ActiveRecord::Bixformer::Model::XXX::Indexed )に渡される
|
112
|
+
# XXX には処理対象のデータ形式(例えば、 Csv )が入ります
|
113
|
+
# 指定可能な値については、「本フレームワークに定義されたModel一覧」を参照
|
114
|
+
type: [:indexed, size: 3]
|
115
|
+
|
116
|
+
}
|
117
|
+
}
|
102
118
|
}
|
103
|
-
|
104
|
-
}
|
105
|
-
```
|
119
|
+
end
|
106
120
|
|
107
|
-
### preferred_skip_attributes
|
108
121
|
|
109
|
-
|
122
|
+
# [bixformer_preferred_skip_attributes] インポート時に、有効な値でない場合に、登録対象としない属性の定義
|
123
|
+
#
|
124
|
+
# - 配列を返すProcオブジェクトかメソッド名/シンボルで指定
|
125
|
+
# - 有効な値については、「インポート時に有効な値」を参照
|
126
|
+
#
|
127
|
+
bixformer_preferred_skip_attributes -> do
|
128
|
+
[
|
129
|
+
# ルートの要素は、対象モデル(上の例なら user )への指定
|
130
|
+
# bixformer_entry で定義されている属性で指定
|
131
|
+
:name,
|
132
|
+
|
133
|
+
# 関連名でも指定可能
|
134
|
+
# この場合は、その関連モデルの処理対象の属性全てが有効な値でない場合に登録対象から外れる
|
135
|
+
:posts,
|
136
|
+
|
137
|
+
# 関連モデルの持つ要素を個別指定したい場合は、最後にハッシュで定義
|
138
|
+
posts: [
|
139
|
+
|
140
|
+
# ここは、postsに対する指定
|
141
|
+
# 上の階層と同じようにネストして定義可能
|
142
|
+
:title
|
143
|
+
|
144
|
+
]
|
145
|
+
]
|
146
|
+
end
|
110
147
|
|
111
|
-
```ruby
|
112
|
-
[
|
113
|
-
# 対象モデル(上の例なら user )の属性名。 entry で定義されていること
|
114
|
-
:name,
|
115
|
-
|
116
|
-
# 関連名も指定可能。この場合は、その関連モデルの処理対象の属性全てが有効な値でない場合
|
117
|
-
:posts,
|
118
|
-
|
119
|
-
# 関連モデルの持つ要素を個別指定したい場合は、ハッシュで定義
|
120
|
-
posts: [
|
121
|
-
# 同じように定義可能
|
122
|
-
:title
|
123
|
-
]
|
124
|
-
]
|
125
|
-
```
|
126
148
|
|
127
|
-
|
149
|
+
# [bixformer_required_attributes] インポート時に、有効な値でない場合に、インポート自体を行わない属性の定義
|
150
|
+
#
|
151
|
+
# - 配列を返すProcオブジェクトかメソッド名/シンボルで指定
|
152
|
+
# - データ構成は、 bixformer_preferred_skip_attributes と同様
|
153
|
+
#
|
154
|
+
bixformer_required_attributes -> do
|
155
|
+
[
|
156
|
+
# joined_atが有効な値でないデータは無視されて、インポートされない
|
157
|
+
:joined_at
|
158
|
+
]
|
159
|
+
end
|
128
160
|
|
129
|
-
有効な値かどうかの判定は、現在、以下の実装となっています。
|
130
161
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
162
|
+
# [bixformer_unique_attributes] インポート時に、 primary_key 以外で更新処理を行う属性の定義
|
163
|
+
#
|
164
|
+
# インポートは、対象の ActiveRecord モデルの primary_key (通常は id )に対応するインポートデータの有無によって、
|
165
|
+
# 追加か更新かを判定しますが、 primary_key の属性がインポートデータに含まれていない場合でも、
|
166
|
+
# 更新処理を行いたい場合に、対象レコードを特定できる属性を設定するためのものです。
|
167
|
+
#
|
168
|
+
# - 配列を返すProcオブジェクトかメソッド名/シンボルで指定
|
169
|
+
# - データ構成は、 bixformer_preferred_skip_attributes と同様
|
170
|
+
#
|
171
|
+
bixformer_unique_attributes -> do
|
172
|
+
[
|
173
|
+
:name, :birthday,
|
174
|
+
|
175
|
+
posts: [:user_id, :title]
|
176
|
+
|
177
|
+
# 上記の場合、 user は name, birthday で特定され、 user.posts は user_id, title で特定されます
|
178
|
+
|
179
|
+
# foreign_key(上記の場合、 user_id )は、bixformer_entry で指定されていなくても構いません
|
180
|
+
# 自動で、データベースの正しい値で補完されます
|
181
|
+
|
182
|
+
# それ以外のもので、インポートデータに有効な値がなかった場合は、更新はせず、追加になります
|
183
|
+
|
184
|
+
# モデルやDBに、実際にユニークインデックスが定義されていなくても指定可能です
|
185
|
+
# ただし、その場合は、条件に合致したレコードが複数あった場合、どれが更新されるか保証できません
|
186
|
+
]
|
144
187
|
end
|
145
|
-
end
|
146
|
-
```
|
147
188
|
|
148
|
-
### required_attributes
|
149
189
|
|
150
|
-
|
151
|
-
|
190
|
+
# [bixformer_required_condition] インポート時に、インポートデータに必ず追加する条件の定義
|
191
|
+
#
|
192
|
+
# - ハッシュを返すProcオブジェクトかメソッド名/シンボルで指定
|
193
|
+
# - bixformer_for で指定されたモデル(上記の場合、 user )のインポートデータに自動で追加されます
|
194
|
+
#
|
195
|
+
bixformer_required_condition -> do
|
196
|
+
{
|
197
|
+
# 対象モデル(上の例なら user )は、現在処理対象になっている group に属している
|
198
|
+
group_id: current_group.id
|
199
|
+
|
200
|
+
# インポートデータに primary_key や bixformer_unique_attributes がある場合、
|
201
|
+
# 更新レコードをデータベース検索しますが、その際にも条件に追加されます
|
202
|
+
|
203
|
+
# 関連モデルの場合は、この設定の有無に関わらず、親レコードの foreign_key が使用されるため、
|
204
|
+
# 関連モデルへの指定はできません
|
205
|
+
|
206
|
+
# primary_key が指定されているのに、データベース検索に失敗した場合には、
|
207
|
+
# ActiveRecord::RecordNotFound 例外が raise されます
|
208
|
+
}
|
209
|
+
end
|
152
210
|
|
153
|
-
### unique_attributes
|
154
211
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
212
|
+
# [bixformer_default_values] インポート時に、有効な値でない場合に、代わりにインポートする値の定義
|
213
|
+
#
|
214
|
+
# - ハッシュを返すProcオブジェクトかメソッド名/シンボルで指定
|
215
|
+
# - この設定は、他の設定項目が全て処理された後のインポートデータに対して処理されます
|
216
|
+
# - インポートデータに対象のキー自体が存在していない( bixformer_preferred_skip_attributes で指定されてる)属性には何もしません
|
217
|
+
#
|
218
|
+
bixformer_default_values -> do
|
219
|
+
{
|
220
|
+
# 単純な値のみ指定可能
|
221
|
+
name: '名無しの権兵衛',
|
222
|
+
|
223
|
+
# 関連モデルに対する指定
|
224
|
+
posts: {
|
225
|
+
title: '無題'
|
226
|
+
}
|
227
|
+
}
|
228
|
+
end
|
159
229
|
|
160
|
-
```ruby
|
161
|
-
[
|
162
|
-
:name, :birthday,
|
163
|
-
posts: [:user_id, :title]
|
164
|
-
]
|
165
|
-
```
|
166
230
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
231
|
+
# [bixformer_translation_config] インポート/エクスポートで行われる translation の設定の定義
|
232
|
+
#
|
233
|
+
# - CSVでは
|
234
|
+
# - カラム名に使用されます
|
235
|
+
#
|
236
|
+
# - ハッシュを返すProcオブジェクトかメソッド名/シンボルで指定
|
237
|
+
# - キーに指定可能な値は、 scope, extend_scopes のいずれか
|
238
|
+
#
|
239
|
+
bixformer_translation_config -> do
|
240
|
+
{
|
241
|
+
# 基点のスコープ
|
242
|
+
scope: :bixformer,
|
243
|
+
|
244
|
+
# translation を検索するスコープを、基点のスコープ配下に増やしたい場合に指定
|
245
|
+
extend_scopes: [:version1, :version2]
|
246
|
+
|
247
|
+
# 上記の場合、ユーザが投稿したタイトルは
|
248
|
+
#
|
249
|
+
# bixformer.version2.user/posts.title
|
250
|
+
# bixformer.version1.user/posts.title
|
251
|
+
# bixformer.user/posts.title
|
252
|
+
#
|
253
|
+
# の順で検索され、最初に見つかった translation を実行します
|
254
|
+
|
255
|
+
# translation が見つからなかったり、失敗した場合は、エラーになります
|
256
|
+
}
|
257
|
+
end
|
172
258
|
|
173
|
-
### required_condition
|
174
259
|
|
175
|
-
|
260
|
+
# [bixformer_load_namespace] 独自クラスを探索する namespace の定義
|
261
|
+
#
|
262
|
+
# - 文字列で指定
|
263
|
+
# - bixformer_entry で指定された独自クラスは、 "ここで指定した値::クラス種別::クラス名" で検索されます
|
264
|
+
# - クラス種別は、 Model, Attribute のいずれかです
|
265
|
+
# - クラス名は、bixformer_entry で指定した値を camelize した値です
|
266
|
+
#
|
267
|
+
bixformer_load_namespace "MyModule::Bixformer"
|
176
268
|
|
177
|
-
|
178
|
-
{
|
179
|
-
# 対象モデル(上の例なら user )は、現在処理対象になっている group に属している
|
180
|
-
group_id: current_group.id
|
181
|
-
}
|
269
|
+
end
|
182
270
|
```
|
183
271
|
|
184
|
-
|
185
|
-
* 関連モデルの場合は、親レコードの foreign_key が代わりに使用されます
|
186
|
-
* `primary_key` が指定されているのに、データベース検索に失敗した場合には、 `ActiveRecord::RecordNotFound` 例外が raise されます
|
187
|
-
|
188
|
-
### default_values
|
272
|
+
### 2. インポート/エクスポートの実装
|
189
273
|
|
190
|
-
|
191
|
-
|
192
|
-
```ruby
|
193
|
-
{
|
194
|
-
name: '名無しの権兵衛',
|
195
|
-
posts: {
|
196
|
-
title: '無題'
|
197
|
-
}
|
198
|
-
}
|
199
|
-
```
|
274
|
+
インポート/エクスポートの処理を定義した Plan と、 ActiveRecord::Bixformer::From/To 配下に
|
275
|
+
定義された各データ形式のインポート/エクスポート用クラスを使います。
|
200
276
|
|
201
|
-
|
277
|
+
以下に、各データ形式の簡単なサンプルを示します。
|
202
278
|
|
203
|
-
|
279
|
+
#### CSVの場合
|
204
280
|
|
205
281
|
```ruby
|
206
|
-
|
207
|
-
# 基点のスコープ
|
208
|
-
scope: :bixformer,
|
209
|
-
|
210
|
-
# translation を試みるスコープを、基点のスコープ配下に増やしたい場合に指定
|
211
|
-
extend_scopes: [:version1, :version2]
|
212
|
-
}
|
213
|
-
```
|
214
|
-
|
215
|
-
上記の場合、ユーザが投稿したタイトルは
|
216
|
-
|
217
|
-
`bixformer.version2.user/posts.title`
|
218
|
-
`bixformer.version1.user/posts.title`
|
219
|
-
`bixformer.user/posts.title`
|
282
|
+
plan = SamplePlan.new
|
220
283
|
|
221
|
-
|
284
|
+
# エクスポート
|
285
|
+
bixformer = ActiveRecord::Bixformer::To::Csv.new(plan)
|
222
286
|
|
223
|
-
|
224
|
-
|
287
|
+
csv_data = CSV.generate do |csv|
|
288
|
+
csv << bixformer.csv_title_row
|
225
289
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
ActiveRecord::Bixformer::Plan::Base には、以下のように定義されています。
|
230
|
-
|
231
|
-
```ruby
|
232
|
-
def module_load_namespaces(module_type)
|
233
|
-
[
|
234
|
-
"::ActiveRecord::Bixformer::#{module_type.to_s.camelize}::#{format.to_s.camelize}",
|
235
|
-
"::ActiveRecord::Bixformer::#{module_type.to_s.camelize}",
|
236
|
-
]
|
290
|
+
User.all.each do |user|
|
291
|
+
csv << bixformer.csv_body_row(user)
|
292
|
+
end
|
237
293
|
end
|
238
|
-
```
|
239
294
|
|
240
|
-
|
241
|
-
|
242
|
-
* `format` は、対象のデータ形式( `:csv` )になります
|
295
|
+
# インポート
|
296
|
+
bixformer = ActiveRecord::Bixformer::From::Csv.new(plan)
|
243
297
|
|
244
|
-
|
298
|
+
CSV.parse(csv_data).each do |csv_row|
|
245
299
|
|
246
|
-
|
300
|
+
if csv_row.header_row?
|
247
301
|
|
248
|
-
|
249
|
-
runner = ActiveRecord::Bixformer::Runner::Csv.new
|
302
|
+
raise ArgumentError unless bixformer.verify_csv_titles(csv_row)
|
250
303
|
|
251
|
-
|
304
|
+
else
|
252
305
|
|
253
|
-
|
306
|
+
attributes = bixformer.assignable_attributes(csv_row)
|
307
|
+
user = User.new
|
308
|
+
|
309
|
+
user.assign_attributes(attributes)
|
310
|
+
user.save!
|
254
311
|
|
255
|
-
|
312
|
+
end
|
313
|
+
end
|
256
314
|
```
|
257
315
|
|
258
316
|
## その他
|
259
317
|
|
260
318
|
### 本フレームワークに定義されたModel一覧
|
261
319
|
|
262
|
-
For CSV
|
320
|
+
#### For CSV
|
263
321
|
|
264
322
|
* base
|
265
323
|
* has_one な関連モデル用。 has_many な関連モデルには使えない
|
@@ -271,8 +329,8 @@ For CSV
|
|
271
329
|
|
272
330
|
### 本フレームワークに定義されたAttribute一覧
|
273
331
|
|
274
|
-
*
|
275
|
-
* エクスポートでは `to_s` し、インポートでは `presence` する
|
332
|
+
* string
|
333
|
+
* エクスポートでは `to_s` し、インポートでは `strip` して `presence` する
|
276
334
|
* boolean
|
277
335
|
* `true` / `false` オプションに、それぞれに対応する文字列を指定。デフォルトは、 `"true"` / `"false"`
|
278
336
|
* インポート時、合致しない値は `nil` になる
|
@@ -294,3 +352,24 @@ For CSV
|
|
294
352
|
* インポートでは、インポートデータ、エクスポートでは、 ActiveRecord の属性値が引数となる
|
295
353
|
* インポート/エクスポートする値を返すこと
|
296
354
|
|
355
|
+
### インポート時に有効な値
|
356
|
+
|
357
|
+
有効な値かどうかの判定は、現在、以下の実装となっています。
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
def presence_value?(value)
|
361
|
+
case value
|
362
|
+
when ::Hash
|
363
|
+
value.values.any? { |v| presence_value?(v) }
|
364
|
+
when ::Array
|
365
|
+
value.any? { |v| presence_value?(v) }
|
366
|
+
when ::String
|
367
|
+
! value.blank?
|
368
|
+
when ::TrueClass, ::FalseClass
|
369
|
+
true
|
370
|
+
else
|
371
|
+
value ? true : false
|
372
|
+
end
|
373
|
+
end
|
374
|
+
```
|
375
|
+
|
@@ -38,7 +38,7 @@ module ActiveRecord
|
|
38
38
|
end
|
39
39
|
|
40
40
|
@preferred_skip_attributes = @plan.pickup_value_for(self, :preferred_skip_attributes, [])
|
41
|
-
@default_values
|
41
|
+
@default_values = @plan.pickup_value_for(self, :default_values, {})
|
42
42
|
|
43
43
|
# At present, translation function is only i18n
|
44
44
|
@translator = ::ActiveRecord::Bixformer::Translator::I18n.new
|
@@ -95,16 +95,26 @@ module ActiveRecord
|
|
95
95
|
@attributes.each do |attr|
|
96
96
|
attribute_value = block.call(attr)
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
# 取り込み時は、オプショナルな属性では、空と思われる値は取り込まない
|
98
|
+
# 取り込み時は、 preferred_skip な属性では、有効でない値は取り込まない
|
101
99
|
next if ! presence_value?(attribute_value) &&
|
102
100
|
@preferred_skip_attributes.include?(attr.name.to_s)
|
103
101
|
|
104
102
|
values[attr.name] = attribute_value
|
105
103
|
end
|
106
104
|
|
107
|
-
|
105
|
+
# データの検証と正規化
|
106
|
+
normalizer.normalize(values).tap do |normalized_values|
|
107
|
+
# デフォルト値の補完
|
108
|
+
@default_values.each do |attribute_name, default_value|
|
109
|
+
# 結果にキーが存在していない( preferred_skip_attributes で指定されてる)場合は補完しない
|
110
|
+
next unless normalized_values.key?(attribute_name)
|
111
|
+
|
112
|
+
# 有効な値が既に格納されている場合も補完しない
|
113
|
+
next if presence_value?(normalized_values[attribute_name])
|
114
|
+
|
115
|
+
normalized_values[attribute_name] = default_value
|
116
|
+
end
|
117
|
+
end
|
108
118
|
end
|
109
119
|
|
110
120
|
def make_each_association_import_value(values, &block)
|
@@ -118,7 +128,7 @@ module ActiveRecord
|
|
118
128
|
association_value = association_value.reject { |v| ! presence_value?(v) }
|
119
129
|
end
|
120
130
|
|
121
|
-
#
|
131
|
+
# 取り込み時は、 preferred_skip な関連では、有効でない値は取り込まない
|
122
132
|
next if ! presence_value?(association_value) &&
|
123
133
|
@preferred_skip_attributes.include?(association.name.to_s)
|
124
134
|
|