LoginSignup
2
0

More than 5 years have passed since last update.

Hanamiでhas_many先のモデルごとcreateする

Last updated at Posted at 2018-05-24

個人的なメモ。マサカリ歓迎!
ツッコミはコメントください!

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のドキュメントを読んでいて、しばらく詰まった :sob:

結局

できるだけ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}]})

懸念点、今後の対応

  1. transactionの考慮まだできてない
    1. Hanami::Repository::ClassMethods#transaction ってなくなっちゃったのかな
  2. created_atupdated_at、自動的に入れてくれへんのかい
    1. hanami側にISSUEあるのかな

そんな感じです

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0