個人的なメモ。マサカリ歓迎!
ツッコミはコメントください!
Hanamiを使っていてツラいと思ったこと
mansion = ::MansionRepository.new.create({ name: 'mansion1' })
room = ::RoomRepository.new.create({ mansion_id: mansion.id, name: 'room1' })
EntityとRepositoryが1対1なので、大きなデータの集約を書き込みたいときにRepository何回も呼び出すことになる
できれば
作成するときは
class HogeRepository
has_many fugas
def hoge_with_fuga(data)
#
end
end
HogeRepository.new.hoge_with_fuga({
hoge_attribute: 'hoge',
fugas: [ {
fuga_attribute: 'fuga'
} ]
})
こんな感じで基底となるEntityのRepositoryから一発で終わらせたい
(更新時は変更範囲に応じたRepositoryでもよいのですが作成時の場合)
class Hanami::Repository < ROM::Repository::Root
なので、ROMではどうやるのか見てみた
rom-rb.org/3.0/learn/repositories/writing-aggregates
class UserRepo < ROM::Repository[:users]
relations :tasks
def create_with_tasks(user)
command(:create, aggregate(:tasks)).call(user)
end
end
user_repo = UserRepo.new(rom)
user_repo.create_with_tasks(
name: 'Jane',
email: 'jane@doe.org',
tasks: [{ title: 'Task 1' }, { title: 'Task 2' }]
)
# => #<ROM::Struct[User] id=1 name="Jane" email="jane@doe.org" tasks=[#<ROM::Struct[Task] id=1 user_id=1 title="Task 1">, #<ROM::Struct[Task] id=2 user_id=1 title="Task 2">]>
ほう。
hanami-mdelが
rom (~> 3.3, >= 3.3.3)
という事をしらずに、rom@4.0.xのドキュメントを読んでいて、しばらく詰まった
結局
できるだけHanamiのAPIを使いたかったので、こうした
class MansionRepository < Hanami::Repository
associations do
has_many :rooms
end
def create_with_rooms(data)
command(:create, aggregate(:rooms)).call(data)
end
end
MansionRepository.new.create_with_rooms( {
name: 'mansion1',
created_at: Time.now,
updated_at: Time.now,
rooms: [{
name: 'room1',
created_at: Time.now,
updated_at: Time.now}]})
懸念点、今後の対応
- transactionの考慮まだできてない
2.Hanami::Repository::ClassMethods#transaction
ってなくなっちゃったのかな -
created_at
とupdated_at
、自動的に入れてくれへんのかい
3. hanami側にISSUEあるのかな
そんな感じです