LoginSignup
18

More than 5 years have passed since last update.

Realmで複数レコードを更新する方法

Last updated at Posted at 2015-05-11

主に一番最後の事例でハマったのでメモ。

前提

Realm 0.92.2を使用

import RealmSwift

class Todo: Object {
  dynamic var id = NSUUID().UUIDString
  dynamic var text = ""
  dynamic var position = 1
  dynamic var createdAt = NSDate()
  dynamic var updatedAt = NSDate()

  override static func primaryKey() -> String? {
    return "id"
  }
}

該当レコードを一括更新する

let realm = Realm()

var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])

realm.write {
  todos.setValue(NSDate(), forKey: "updatedAt")
}

v0.91.2で追加されたsetValueを使って更新する。

該当レコードを1つずつ更新する

filterの値以外を更新する場合

let realm = Realm()

var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])

realm.write {
  for todo in todos {
    todo.name += "hogehoge"
    todo.updatedAt = NSDate()
  }
}

for inで回して更新する。

filterの値を更新する場合

let realm = Realm()

var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])

realm.write {
  var ids: [String] = []
  for todo in todos {
    ids.append(todo.id)
  }
  for id in ids {
    if var todo = realm.objectForPrimaryKey(Todo.self, key: id) {
      todo.position++
      todo.updatedAt = NSDate()
    }
  }
}

Resultsをそのままfor inで回して更新する方法では、Results自体が更新されてしまって上手く処理出来ない。
一旦該当レコードのprimaryKeyを取得してから、改めて更新処理を実行すると上手くいく。

若干コードの見通しが悪いので、もし以外で良い方法があれば教えてください。

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
18