LoginSignup
1
1

More than 3 years have passed since last update.

Roomのリレーションで悩んでいたら、リレーション実現しなくても実装出来た

Last updated at Posted at 2020-03-25

Roomで1対1対応のリレーションを実現したい

Roomを使ったアプリケーションで、別々のテーブルの情報が両方必要なので、昔Railsを触った自分としては、

「ついにAndroidのRoomでもリレーションを実現しなければならない時が来た」

と思いました。
そこでドキュメントなど、色々見ていたのですがRoomで1対1対応のリレーションは、ズバリこう実装すれば良いというのがイマイチ分からないでいました。
ActiveRecordでいうhas_oneのような物は無いのでしょうか。

ところが「参照するだけなら、そもそもRoomでリレーション組まなくても実装できる」という話を聞いて、自分は最初よく理解出来ませんでした。

DBでリレーション使わず、実現した方法

今回はサンプルとして、仮にゲームのQuestionテーブルとScoreテーブルとします。

// データモデルQuestion
id: Int
level: Int
number: Int
question: String
created_at: String
// データモデルScore
id: Int
level: Int
number: Int
time: Int
score: Int
clear_date: String

この2つを関連づけたいとします。このQuestionテーブルに対応したScoreを結び付けたい。必要な情報を抽出して、

// QuestionとScoreをまとめて扱う、QuestionAndScoreクラス

class QuestionAndScore {
    companion object {
        fun createQuestionAndScore(level: Int, number: Int, question: String): QuestionAndScore {
            return QuestionAndScore().apply {
                this.level = level
                this.number = number
                this.question = question
            }
        }
    }
    var level: Int = 0
    var number: Int = 0
    var question: String = ""
    var time: String = ""
}

2つのテーブルの情報を同時に扱うQuestionAndScoreクラスを作成しました。

  • 今回はQuestion情報に対する最高スコアを組み合わせた問題リストを作成することにします。

val allQuestions = getAllQuestions() //全ての問題データを取得する
val allScores = getAllScores()  //全てのスコアデータ取得

// 問題データとスコアデータを組み合わせたリスト
val allQuestionsAndScores = mutableListOf<QuestionAndScore>().apply {
    allQuestions.forEach { questionData ->
        val level = questionData.level
        val number = questionData.number
        val question = questionData.question
        val questionAndScore = createQuestionAndScore(level, number, questoin)
        // 関連するスコアだけを取り出す
        val scoreList = allScores.filter { scoreData ->
            scoreData.level == level && scoreData.number == number
        }
        // 最高スコアを取得
        val maxScore = scoreList.maxby {
            it.score
        }!!.score
        questionAndScore.score = maxTime
        add(questionAndScore)
    }
}

これで問題情報と各問題の最高スコアを組み合わせた問題リストが作成出来ました。

値を参照するだけなら、このように実現することが出来ました。

1
1
1

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