ActiveModel::Model を使って、initializer を消してみた
ActiveModel::Model を使って、initializer を消してみた
ActiveModel::Model
を使うと Before
-> After
のように initializer
を消せることを知りました。
Before
今まで、自分は initializer
を使って実装していました。
class Before
attr_accessor :attr
def initialize(attr:)
@attr = attr
end
end
[1] pry(main)> before = Before.new(attr: 'before')
=> #<Before:0x00007f51c20d8ca0 @attr="before">
[2] pry(main)> before.attr
=> "before"
After
initializer
を書かずに、シンプルにかけます。
class After
include ActiveModel::Model
attr_accessor :attr
end
[1] pry(main)> after = After.new(attr: 'after')
=> #<After:0x00007f51c0324ee8 @attr="after">
[2] pry(main)> after.attr
=> "after"
ActiveModel::Model について
調査して、いろいろ試してみました。
ActiveModel::Model を追加すると?
ActiveModel::Model
を追加すると、Action Pack
やAction View
と連携する機能をすぐに使えるようになります。
include ActiveModel::Model なし
まず、ActiveModel::Model
を使わない場合、どういうふうに実装できるか試してみました。
initializer を使う
class A
attr_accessor :attr
def initialize(attr:)
@attr = attr
end
end
[1] pry(main)> a = A.new(attr: 'a')
=> #<A:0x0000000009b53ed0 @attr="a">
[2] pry(main)> a.attr
=> "a"
ActiveModel::Model の実装を参考にして動かす
下記の ActiveModel::Model
の実装をそのまま持ってきて、動かしてみました。
class B
include ActiveModel::AttributeAssignment
attr_accessor :attr
def initialize(attributes = {})
assign_attributes(attributes) if attributes
end
end
[2] pry(main)> b = B.new(attr: 'b')
=> #<B:0x00007f9f6808def0 @attr="b">
[3] pry(main)> b.attr
=> "b"
ActiveModel::Model を使ってみる
attr_accessor
attr_accessor
を使うと、書き込みも読み取りもできます。
class C
include ActiveModel::Model
attr_accessor :attr
end
[1] pry(main)> c = C.new(attr: 'c')
=> #<C:0x00007ff4935dd0b0 @attr="a">
[2] pry(main)> c.attr
=> "c"
include ActiveModel::Model なし
ActiveModel::Model
を include
しない場合、initializer
が定義されていないため、引数が渡せず ArgumentError
で落ちます。
class D
attr_accessor :attr
end
[1] pry(main)> d = D.new(attr: 'd')
ArgumentError: wrong number of arguments (given 1, expected 0)
from (pry):1:in `initialize'
[2] pry(main)> d = D.new
=> #<A:0x00007f9f5e52f5a8>
[3] pry(main)> d.attr
=> nil
attr_reader
attr_reader
だと、書き込めないため ActiveModel::UnknownAttributeError
で落ちます。
class E
include ActiveModel::Model
attr_reader :attr
end
[1] pry(main)> e = E.new(attr: 'e')
ActiveModel::UnknownAttributeError: unknown attribute 'attr' for E.
from /Users/username/.rbenv/versions/2.5.7/lib/ruby/gems/2.5.0/gems/activemodel-5.2.3/lib/active_model/attribute_assignment.rb:53:in `_assign_attribute'
attr_writer
attr_writer
だと、読み込めないため NoMethodError
で落ちます。
class F
include ActiveModel::Model
attr_writer :attr
end
[1] pry(main)> f = F.new(attr: 'f')
=> #<F:0x00007ff49df74678 @attr="f">
[2] pry(main)> f.attr
NoMethodError: undefined method `attr' for #<F:0x00007ff49df74678 @attr="f">
from (pry):1:in `<main>'