LoginSignup
1
1

More than 5 years have passed since last update.

【注意:動作しません】【Realm】【Kotlin】RealmでEnumフィールドを定義するとKotlinならここまで楽になる

Last updated at Posted at 2016-07-23

以下の方法では動きません

以下で記載されている方法では動作しません。
すみません。

どんな記事?

RealmのフィールドにはEnumなどの型サポートがないので、
特定の値しか入らないようなフィールドを自作した。

そんで、Kotlinを使うとここまで楽になったよという話。

今回は分かりやすくするために普通のRDBと同じ用語を使います。

Enumでsafetyにしたい

例えば PERSONというテーブルにPEREFCTUREという都道府県が入るカラムがあるとします。
当然ここには、存在する都道府県以外の名称は入ってほしくないですよね。

特定の値しか許容しない仕組みといえば、列挙型(Enum)ですが、
RealmではEnum型のフィールドはサポートしていないようです。

じゃあ、自作してしまおう。

早速コード

PrefectureEnum.kt
enum class PrefectureEnum(val value: String) {
    TOKYO("東京都"),
    KANAGAWA("神奈川県"),
    // .....以下47都道府県
}
Person.kt
class Person(
    /** 名前 */
    @Required @PrimaryKey open var name: String = "",
    /** 都道府県 */
    prefecture: String = ""

    companion object {
        // 値が含まれているかをチェックする
        @JvmStatic fun contains(value: String): Boolean {
            return values().map { it.value }.contains(value)
        }
    }


) : RealmObject() {
    open var prefecture: String = ""
        //カスタムゲッターでEnum以外の値は取得できないようにする
        get() = if (PrefectureEnum.contains(field) field else "あなたどこ出身?"
        //カスタムセッターでEnum以外の値はセットできないようにする
        set(value) {
            if (PrefectureEnum.contains(value)) field = value
            else field = "あなたどこ出身?"
        }

    init {
        this.prefecture = prefecture
    }
}

Enumクラスに独自のcontainsメソッドを定義

Enum.valuesだとEnum型の配列として取得されるので、mapで値の配列に変換してから
containsで値が含まれているかのチェックを行うようにしました。

Streamが手軽に使えるのはKotlinの大きな強みっすね。

Personクラスにカスタムセッターゲッターを定義

特定のフィールドにEnumを適応したい場合には
カスタムセッターとゲッターを指定するのがポイント。

Enumクラスで定義した値が含まれていなかったときには、それ専用の値を入れてます。
注意点はcontainsの引数や戻り値には直接のプロパティを渡してはいけないところ。

プロパティ自体を渡すと自分のgetter/setterが再び呼ばれるのでスタックオーバーフローで死にます。
必ず、値だけを渡すようにfieldを指定してください。

Kotlinサイコーかよ

Kotlinのカスタムゲッター、セッターが存分に活かされたとこです。
StreamもAndroidでJava8が対応したとはいえ、まだ一部機能は制限されてますからね。

というわけでKotlinはやっぱ良い。

1
1
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
1
1