choron_support 0.1.9 → 0.1.11

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.
@@ -1,381 +1,218 @@
1
- # 本クラス は include 先のクラスに対してキャメルケースのJSONを設定するためのDSLやメソッドを提供するモジュールです
2
- # このモジュールをincludeしたクラスは以下のような形で使うことを想定しています
3
- # @examle
4
- # [app/models/values/money.rb]
5
- # class Values::Money
6
- # include ChoronSupport::Props::Attributes
7
- # attributes :amount, :amount_with_unit, to: :self
8
- # def initialize(amount)
9
- # @amount = amount.to_i
10
- # end
11
- # def amount
12
- # @amount
13
- # end
14
- # def amount_with_unit
15
- # "#{amount}円"
16
- # end
17
- # end
18
- # Choronではデフォルトで以下のようなBaseクラスが作成されて、読み込みがされています
19
- # @example
20
- # class Props::Base < ChoronSupport::Props::Base
21
- # include ChoronSupport::Props::Attributes
22
- # end
23
- # [使い方]
24
- # @example 最も簡単な例
25
- # [app/models/props/user.rb]
26
- # class Props::User < Props::Base
27
- # # id, full_name, ageを出力させる
28
- # # retult: { id: 1, fullName: "John Smith", age: 20 }
29
- # attributes :id, :full_name, :age
30
- # end
31
- # @example メソッドのデリゲート先を指定する
32
- # [app/models/props/user.rb]
33
- # class Props::User < Props::Base
34
- # # result: { fullName: "John Smith" }
35
- # attributes :full_name, to: :self
36
- # def full_name
37
- # "#{model.first_name} #{model.last_name}"
38
- # end
39
- # end
40
- # @example 関連先のModelのPropsを結合する
41
- # class Props::User < Props::Base
42
- # # result: { posts: posts.as_props } => { posts: [{ id: 1, title: "foo" }, { id: 2, title: "bar" }] }
43
- # relation :posts
44
- # end
45
- #
46
- # これらの各種DSLは複数同時に設定することもできます
47
- # @example 複数設定
48
- # [app/models/props/user.rb]
49
- # class Props::User < Props::Base
50
- # # id, full_name, ageを出力させる
51
- # attributes :id, :age
52
- # attributes :full_name, to: :self
53
- # relation :posts
54
- # def full_name
55
- # "#{model.first_name} #{model.last_name}"
56
- # end
57
- # end
58
- #
59
- # default値の設定やifオプションを渡して出力有無を動的に変更もできます
60
- # @example default, ifの設定
61
- # [app/models/props/user.rb]
62
- # class Props::User < Props::Base
63
- # # age が nil のときは 0 を出力する
64
- # # age が 20 以上のときのみ出力する
65
- # attributes :age, default: 0, if: :show_age?
66
- # def show_age?
67
- # model.age >= 20
68
- # end
69
- # end
70
- #
71
- #
72
- # 本DSLを利用するときは基本的には attributes を使って設定するのが良いと思います
73
- # 細かな使い方モジュールの該当DSL(self.xxxx)の説明を参照してください
74
- module ChoronSupport
75
- module Props
76
- module Attributes
77
- FORMATS = {
78
- # HTMLのinput type="date"で使える形式
79
- date: "%Y-%m-%d",
80
- datetime: "%Y-%m-%dT%H:%M",
81
- }.freeze
82
- # 型のキャスト指定があってもキャストはしないメソッド
83
- CAST_IGNORE_METHODS = [
84
- # id は数値のほうが良いため
85
- :id,
86
- ].freeze
87
- # デフォルト値を設定しない場合に使う値
88
- NO_DEFAULT = Object.new.freeze
1
+ require_relative "./private/setting"
2
+ module ChoronSupport::Props::Attributes
3
+ unless defined?(ActiveSupport)
4
+ raise "ActiveSupport is not defined. Please require 'active_support/all' in your Gemfile"
5
+ end
89
6
 
90
- extend ActiveSupport::Concern
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ # DSLで設定できる設定値たち ==========================
11
+ # Props作成時に設定されるキーと値を設定します。
12
+ # この値はDSLを経由して内部的に設定されていきます
13
+ class_attribute :settings, instance_writer: false, default: nil
14
+ # Props作成時に自動で付与される元のクラスの文字列を設定しないときはtrueを設定してください
15
+ # @example
16
+ # class Props::Foos::Bar
17
+ # self.skip_meta_mark = true
18
+ # end
19
+ class_attribute :skip_meta_mark, default: false
20
+ # 他のPropsクラスの設定を継承するときに設定されます。設定できるのは1つだけです
21
+ class_attribute :inherit_props_class, default: nil
22
+ # ====================================================
23
+
24
+ # Propsとして出力する属性を設定するためのDSLです
25
+ # @param [Symbol] method モデル, もしくは to オプションで設定したオブジェクトに対して実行するメソッドを指定してください
26
+ # @param [Keyword] options その他のオプションを指定してください
27
+ # @option [Symbol] :to 指定したメソッドを実行するオブジェクトを指定できます
28
+ # @option [Symbol] :name Props化するときに出力する属性(Key)名を指定できます
29
+ # @option [Symbol | lambda] :if 属性を出力するための条件を指定できます
30
+ # @option [Symbol] :cast 属性を出力する前に指定したメソッドを実行できます。
31
+ # @option [Boolean] :default 属性値がnilのときに代わりに出力する値を指定できます
32
+ # @option [Proc] &block ブロックを渡すとそのブロックの戻り値を属性値として出力します
33
+ def self.attribute(method, **options, &block)
34
+ setting_params = options.merge(method:, block:)
35
+ setting = ChoronSupport::Props::Private::Setting.new(setting_params)
36
+
37
+ self.settings ||= []
38
+ self.settings << setting
39
+ end
91
40
 
92
- included do
93
- # 本moduleはActiveSupportが使える環境でのみ動作します
94
- unless defined?(ActiveSupport)
95
- raise "ActiveSupport is not defined. Please require 'active_support/all' in your Gemfile"
96
- end
41
+ # 他のPropsクラスの設定を継承するためのDSLです
42
+ # @param [ChoronSupport::Props::Base] inherit_props_class 継承するPropsクラスを指定してください
43
+ # @example
44
+ # class Props::Users::General < ChoronSupport::Props::Base
45
+ # inherit Props::Users::Base
46
+ # end
47
+ def self.inherit(props_class)
48
+ # 継承するクラスはProps::Baseを継承している必要があります
49
+ unless props_class.method_defined?(:as_props)
50
+ raise "inherit class must be respond to :as_props. #{props_class} is not respond to :as_props"
51
+ end
97
52
 
98
- # DSLで設定できる設定値たち ==========================
99
- # Props作成時に設定されるキーと値を設定します。
100
- # この値はDSLを経由して内部的に設定されていきます
101
- class_attribute :settings_attributes
102
- # Props作成時に自動で付与される元のクラスの文字列を設定しないときはtrueを設定してください
103
- # @example
104
- # class Props::Foo < Props::Base
105
- # self.skip_meta_mark = true
106
- # end
107
- class_attribute :skip_meta_mark, default: false
108
- # 他のPropsクラスの結果を結合するときに結合先のProps識別子を設定してください
109
- # @example
110
- # class Props::Foos::General < Props::Base
111
- # # すべてのカラムを出す
112
- # self.union = :model
113
- # # as_props の結果を結合する
114
- # self.union = :default
115
- # # as_props(:secure) の結果を結合する
116
- # self.union = :secure
117
- # end
118
- class_attribute :union, default: nil
119
- # ====================================================
53
+ # 既に継承先が設定されている場合はエラーにします
54
+ if inherit_props_class.present?
55
+ raise "inherit props inherit class already set: #{inherit_props_class}.(Only one class can be inherited)"
56
+ end
120
57
 
121
- # Props作成時に設定されるキーと値を設定します。
122
- # @param [Symbol] key Propsのキーを指定してください
123
- # @param [Symbol] method 値を代入するためのメソッドを指定してください。指定がないときはkeyをメソッドとして扱います
124
- # @param [Symbol] to メソッドのデリゲート先を指定してください。指定がないときはmodelをデリゲート先として扱います。:selfを指定すると自身をデリゲート先として扱います
125
- # @param [Symbol] cast デリゲート先のメソッドの戻り値に対して、さらにメソッドを実行するときは指定してください。
126
- # @param [Object] default 値がnilのときに設定されるデフォルト値を指定してください。指定がないときはnilになります。
127
- # @param [Proc | Symbol] if その値を出すときの条件。Symbolだとselfに対してsendを実行します
128
- def self.attribute(key, method: nil, to: :model, cast: nil, default: NO_DEFAULT, if: nil)
129
- self.settings_attributes ||= []
130
- self.settings_attributes << { key:, to:, method: (method || key), cast:, default:, if: }
131
- end
58
+ self.inherit_props_class = props_class
59
+ self.settings ||= []
60
+ inherit_props_class.settings.to_a.each do |setting|
61
+ self.settings << setting
62
+ end
63
+ end
132
64
 
133
- # 一度にまとめて複数のattributeを設定します
134
- # 基本的なパラメータの説明はattributeを参照してください
135
- # @param [Array<Symbol>] methods 設定するキーと値のペアを指定してください
136
- # @example
137
- # model = User.new(id: 1, name: "John", email: "JOHN@EXAMPLE", age: nil)
138
- # class Props::User::Foo < ChoronSupport::Props::Base
139
- # attributes :id, :name, :email, :age
140
- # #=> { id: 1, name: "John", email: "JOHN@EXAMPLE", age: nil }
141
- # end
142
- # @note to, cast, defaultなどのパラメータについて
143
- # これらの値は全てのメソッド・キーに対して同じ値が設定されます
144
- def self.attributes(*methods, to: :model, cast: nil, default: NO_DEFAULT, if: nil)
145
- methods.each do |method|
146
- attribute(method, method:, to:, cast:, default:, if:)
147
- end
148
- end
65
+ # Modelに対して関連付けされた別ModelのPropsを結合するためのDSLです
66
+ # @param [Symbol] method to オプションで指定されたオブジェクトに実行されるメソッドを指定してください
67
+ # @param [ChoronSupport::Props::Base | Symbol] props_class モデルをProps化するためのクラス もしくはそれを示す Symbol を指定してください
68
+ # @param [Array<Symbol>] only 指定した属性のみを出力します
69
+ # @param [Array<Symbol>] except 指定した属性を除外して出力します
70
+ # @param [Symbol] sti 継承元のクラスのPropsを利用したいときにtrueを指定してください
71
+ # @param [Keyword] options その他のオプションを指定してください。詳細は attribute と同じです
72
+ # @example
73
+ # class Props::Users::General < ChoronSupport::Props::Base
74
+ # relation :posts, :general, only: %i[id title]
75
+ # #=> { posts: user.posts.as_props(:general, only: %i[id title]) } と同じ結果になる
76
+ # end
77
+ def self.relation(method, props_class, only: nil, except: nil, sti: false, **options)
78
+ attribute(method, **options) do |model, params|
79
+ records = model.send(method)
80
+ # only等の設定はrelationで設定したものを適用する
81
+ params.merge!(only:, except:, sti:)
82
+ records&.as_props(props_class, **params)
83
+ end
84
+ end
85
+ end
149
86
 
150
- # Modelに対して関連付けされた別ModelのPropsを結合するためのDSLです
151
- # to, cast, default, if については attribute と同じです
152
- # @param [Symbol] key Propsのキーを指定してください
153
- # @param [Symbol] relation 結合するModelのメソッドを指定してください。指定がないときはkeyをメソッドとして扱います
154
- # @example
155
- # class Props::User < ChoronSupport::Props::Base
156
- # relation :posts
157
- # #=> { posts: user.posts.as_props } と同じ結果になる
158
- # relation :posts, props: :foo_bar
159
- # #=> { posts: user.posts.as_props(:foo_bar) } と同じ結果になる
160
- # relation :user_posts, relation: :posts
161
- # #=> { user_posts: user.posts.as_props } と同じ結果になる
162
- # end
163
- def self.relation(key, relation: nil, to: :model, cast: nil, default: NO_DEFAULT, props: nil, if: nil)
164
- relation ||= key
165
- method = lambda { |model|
166
- records = model.send(relation)
167
- if props
168
- records&.as_props(props) || {}
169
- else
170
- records&.as_props || {}
171
- end
172
- }
173
- self.attribute(
174
- key,
175
- method:,
176
- to:,
177
- cast:,
178
- default:,
179
- if:,
180
- )
181
- end
87
+ # @return [Hash] props
88
+ def as_props
89
+ _props = {}
90
+ only_params = params[:only].to_a.map(&:to_sym)
91
+ except_params = params[:except].to_a.map(&:to_sym)
182
92
 
183
- # self.relation の複数同時に設定ができるversionです
184
- # 基本は上記と一緒ですが、relationとkeyは同じである必要があります
185
- # @example
186
- # class Props::User < ChoronSupport::Props::Base
187
- # relations :posts, :comments
188
- # #=> { posts: user.posts.as_props, comments: user.comments.as_props } と同じ結果になる
189
- # end
190
- def self.relations(*keys, to: :model, cast: nil, default: NO_DEFAULT, props: nil, if: nil)
191
- keys.each do |key|
192
- method = lambda { |model|
193
- records = model.send(key)
194
- if props
195
- records&.as_props(props) || {}
196
- else
197
- records&.as_props || {}
198
- end
199
- }
200
- self.attribute(
201
- key,
202
- method:,
203
- to:,
204
- cast:,
205
- default:,
206
- if:,
207
- )
208
- end
209
- end
93
+ # DSLの設定を設定する
94
+ self.class.settings.to_a.each do |setting|
95
+ # 除外設定がある場合はスキップ
96
+ next if except_params.include?(setting.method.to_sym)
97
+ # only設定がある場合はそれ以外をスキップ
98
+ next if only_params.present? && only_params.exclude?(setting.method.to_sym)
210
99
 
211
- # Propsに設定されるキーと値のペアを返します
212
- # @param 各種パラメータは self.attribute に合わせているためそちらを参照してください
213
- # @return [Hash] 設定されるPropsのキーと値のペア
214
- # @note memo
215
- # if が予約語のため options として受け取っています。_ifも検討しましたが全体でキーワードの形を合わせたかったためoptionsの形にしています
216
- def attribute(key, method: nil, to: :model, cast: nil, default: NO_DEFAULT, **options)
217
- __build_props_attribute__(key, (method || key), to, cast, default, **options)
218
- end
100
+ _props.merge!(__build_props_attribute__(setting))
101
+ end
219
102
 
220
- # 一度にまとめて複数のattributeを設定します
221
- # パラメータは self.attributes に合わせているためそちらを参照してください
222
- def attributes(*methods, to: :model, cast: nil, default: nil, **options)
223
- _props = {}
224
- methods.each do |method|
225
- key = method.to_sym
226
- unit_props = __build_props_attribute__(key, method, to, cast, default, **options)
103
+ # Classのマークをつける(テスト用)
104
+ _props.merge!(__build_props_class_mark__)
105
+ # Modelのマークをつける
106
+ _props.merge!(__build_props_meta_mark__)
227
107
 
228
- _props.merge!(unit_props)
229
- end
108
+ _props
109
+ end
230
110
 
231
- # ブロックが渡されていれば実行する
232
- if block_given?
233
- _props = yield(_props)
234
- end
111
+ private
112
+
113
+ def model
114
+ raise NotImplementedError, "model method is not implemented. Please implement model method in your class"
115
+ end
235
116
 
236
- # Classのマークをつける(テスト用)
237
- _props.merge!(__build_props_class_mark__)
238
- # Modelのマークをつける
239
- _props.merge!(__build_props_meta_mark__)
117
+ def params
118
+ {}
119
+ end
240
120
 
241
- _props
242
- end
121
+ FORMATS = {
122
+ # HTMLのinput type="date"で使える形式
123
+ date: "%Y-%m-%d",
124
+ datetime: "%Y-%m-%dT%H:%M"
125
+ }.freeze
126
+ # 型のキャスト指定があってもキャストはしないメソッド
127
+ CAST_IGNORE_METHODS = [
128
+ # id は数値のほうが良いため
129
+ :id
130
+ ].freeze
131
+ # @param [Array<Symbol>] Setting
132
+ def __build_props_attribute__(setting)
133
+ attribute = {}
134
+
135
+ _if = setting.if
136
+ if _if.present?
137
+ result = send(_if)
138
+ return {} unless result
139
+ end
243
140
 
244
- # @override
245
- # Props::Base#as_props をオーバーライドしています
246
- # 本モジュールを読み込んだクラスではas_propsはオーバーライドせず、DSLとpropsメソッドを上書きしてください
247
- # @note 仕様
248
- # クラス側で設定されたattribute, attributesを元にPropsを作成します
249
- # もしくはオーバーライドされているであろう props の結果を設定します
250
- # もし両方を設定しているときはどちらの値も設定されます
251
- # キーがかぶっているときはprops側が優先されます
252
- # @return [Hash] props
253
- def as_props
254
- _props = {}
141
+ # javascriptは?をキーとして使えないので削除しつつ、isXxx形式に変換する
142
+ key = setting.name
143
+ if key.to_s.end_with?("?")
144
+ key = key.to_s.gsub("?", "").to_sym
145
+ key = "is_#{key}".to_sym unless key.start_with?("is_")
146
+ end
255
147
 
256
- # 結合先が指定されていればその結合先のpropsを取得する
257
- if self.class.union.present?
258
- if self.class.union == :default
259
- _props.merge!(model.as_props)
148
+ # javascriptは!をキーとして使えないので削除する
149
+ key = key.to_s.gsub("!", "").to_sym if key.to_s.end_with?("!")
150
+
151
+ method = setting.method
152
+ to = setting.to
153
+ # valはこの後の工程で書き換えの可能性があるため注意
154
+ val = if setting.block.present?
155
+ setting.block.call(model, params)
156
+ elsif to == :self
157
+ if method.is_a?(Proc)
158
+ method.call(self)
260
159
  else
261
- _props.merge!(model.as_props(self.class.union))
160
+ send(method)
262
161
  end
263
- end
264
-
265
- # DSLの設定があればそれを設定する
266
- self.class.settings_attributes.to_a.each do |settings|
267
- _props.merge!(
268
- attribute(settings[:key], method: settings[:method], to: settings[:to], cast: settings[:cast], default: settings[:default], if: settings[:if])
269
- )
270
- end
271
-
272
- # Classのマークをつける(テスト用)
273
- _props.merge!(__build_props_class_mark__)
274
- # Modelのマークをつける
275
- _props.merge!(__build_props_meta_mark__)
276
- # Propsがオーバーライドされていればその値で上書きする
277
- _props.merge!(self.props)
278
-
279
- _props
280
- end
281
-
282
- # @return [Hash] props
283
- # @note
284
- #  オーバーライドして使うことを想定しています
285
- def props
286
- {}
287
- end
288
- end
289
-
290
- private
291
-
292
- # @param [Array<Symbol>] methods
293
- # @param [Symbol] key
294
- # @param [Symbol] to メソッドのデリゲート先
295
- # @param [Block] blockを渡すと実行結果をブロック引数でわたし、その中の戻り値を結果として返します
296
- # @param [Symbol] cast デリゲート先のメソッドの戻り値に対して、さらにメソッドを実行する
297
- # 複雑性を増す代わりに集約をさせています
298
- def __build_props_attribute__(key, method, to, cast, default, **options)
299
- props = {}
300
-
301
- _if = options[:if]
302
- if _if.present?
303
- result = _if.is_a?(Proc) ? _if.call(model) : send(_if)
304
- return {} unless result
305
- end
306
-
307
- # javascriptは?をキーとして使えないので削除しつつ、isXxx形式に変換する
308
- if key.to_s.end_with?("?")
309
- key = key.to_s.gsub("?", "").to_sym
310
- key = "is_#{key}".to_sym unless key.start_with?("is_")
311
- end
312
-
313
- # valはこの後の工程で書き換えの可能性があるため注意
314
- if to == :self
315
- if method.is_a?(Proc)
316
- val = method.call(self)
317
- else
318
- val = send(method)
319
- end
320
- else
321
- if method.is_a?(Proc)
322
- val = method.call(send(to))
162
+ elsif method.is_a?(Proc)
163
+ method.call(send(to))
323
164
  else
324
- val = send(to)&.send(method)
165
+ send(to)&.send(method)
325
166
  end
326
- end
327
167
 
328
- case val
329
- when Date
330
- val = val.strftime(FORMATS[:date])
331
- when ActiveSupport::TimeWithZone, Time
332
- # 日付系であればjsで使えるようにhtmlに変換する
333
- val = val.strftime(FORMATS[:datetime])
334
- else
335
- if cast.present? && CAST_IGNORE_METHODS.exclude?(key)
336
- val = cast.to_s.split(".").inject(val) do |lval, cast_method|
337
- lval.send(cast_method)
338
- end
339
- end
340
- end
341
-
342
- if val.nil? && default != NO_DEFAULT
343
- val = default
168
+ case val
169
+ when Date
170
+ val = val.strftime(FORMATS[:date])
171
+ when ActiveSupport::TimeWithZone, Time
172
+ # 日付系であればjsで使えるようにhtmlに変換する
173
+ val = val.strftime(FORMATS[:datetime])
174
+ else
175
+ if setting.cast.present? && CAST_IGNORE_METHODS.exclude?(key)
176
+ val = setting.cast.to_s.split(".").inject(val) do |lval, cast_method|
177
+ lval.send(cast_method)
344
178
  end
179
+ end
180
+ end
345
181
 
346
- props[key] = val
182
+ val = setting.default if val.nil? && setting.set_default?
347
183
 
348
- props
349
- end
184
+ attribute[key] = val
350
185
 
351
- # テストモードのときはどのPropsを実行したかを判定できるように属性をつけたします
352
- def __build_props_class_mark__
353
- mark = {}
354
- if ENV["RAILS_ENV"] == "test"
355
- mark[:props_class_name] = self.class.name
356
- if self.class.union.present?
357
- mark[:union_type_name] = self.class.union
358
- end
359
- end
186
+ attribute
187
+ end
360
188
 
361
- mark
189
+ # テストモードのときはどのPropsを実行したかを判定できるように属性をつけたします
190
+ def __build_props_class_mark__
191
+ mark = {}
192
+ if ENV["RAILS_ENV"] == "test"
193
+ mark[:props_class_name] = self.class.name
194
+ if self.class.inherit_props_class.present?
195
+ mark[:inherit_props_class_name] =
196
+ self.class.inherit_props_class.try(:name) || self.class.inherit_props_class.to_s
362
197
  end
198
+ end
363
199
 
364
- # どのモデルのPropsかを判定できるように属性をつけたします
365
- def __build_props_meta_mark__
366
- return {} if self.class.skip_meta_mark
200
+ mark
201
+ end
367
202
 
368
- type_target = begin
369
- model
370
- rescue StandardError
371
- self
372
- end
203
+ # どのモデルのPropsかを判定できるように属性をつけたします
204
+ def __build_props_meta_mark__
205
+ return {} if self.class.skip_meta_mark
373
206
 
374
- {
375
- type: type_target.class.try(:name).to_s,
376
- model_name: type_target.class.try(:name).try(:demodulize).to_s,
377
- }
378
- end
207
+ type_target = begin
208
+ model
209
+ rescue StandardError
210
+ self
379
211
  end
212
+
213
+ {
214
+ type: type_target.class.try(:name).to_s,
215
+ model_name: type_target.class.try(:name).try(:demodulize).to_s
216
+ }
380
217
  end
381
218
  end
@@ -1,40 +1,26 @@
1
- # 本クラスはChoronSupportを利用しているRailsで継承されることを想定して作成されてます
2
- # Choronでは以下のようにBaseクラスがデフォルトで作成されています
3
- # @example
4
- # [app/models/props/base.rb]
5
- # class Props::Base < ChoronSupport::Props::Base
6
- # include ChoronSupport::Props::Attributes
7
- # end
8
- # そして各種モデルのPropsは上記のBaseクラスを継承して作成されています
9
- # @example
10
- # [app/models/props/user.rb]
11
- # class Props::User < Props::Base
12
- # attributes :id, :name, :age
13
- # end
14
- # [app/models/props/users/secure.rb]
15
- # class Props::Users::Secure < Props::Base
16
- # # secure側はageは非表示
17
- # attributes :id, :name
18
- # end
1
+ require_relative "./attributes"
2
+
19
3
  module ChoronSupport
20
4
  module Props
21
5
  class Base
6
+ include ChoronSupport::Props::Attributes
7
+
22
8
  # @param [ActiveRecord::Base] model Props対象のモデルのインスタンス
23
9
  # @param [Hash] params その他のパラメータ
10
+ # @param [Boolean] params params[:only] 指定した属性のみを出力します
11
+ # @param [Boolean] params params[:except] 指定した属性を出力しません
24
12
  def initialize(model, params = {})
25
13
  @model = model
26
- @params = params
27
- end
28
-
29
- # 継承先で実装されることを想定しています
30
- # ChoronSupport::Props::Attributes を読み込んでいるときは、そちらでオーバーライドされています
31
- def as_props
32
- raise NotImplementedError
14
+ @params = params.to_h
33
15
  end
34
16
 
35
17
  private
36
18
 
37
- attr_reader :model, :params
19
+ # @override
20
+ attr_reader :model
21
+
22
+ # @override
23
+ attr_reader :params
38
24
  end
39
25
  end
40
26
  end
@@ -6,4 +6,4 @@ class Hash
6
6
  def to_camel_json
7
7
  as_camel_json.to_json
8
8
  end
9
- end
9
+ end
@@ -5,6 +5,6 @@ class ActiveRecord::Relation
5
5
  return {}
6
6
  end
7
7
 
8
- records.map {|record| record.as_props(type_symbol, **params) }
8
+ records.map { |record| record.as_props(type_symbol, **params) }
9
9
  end
10
10
  end