Samuele Pontremoli
Samuele Pontremoli

Reputation: 594

Retrofit to Room models mapping

I have a question that maybe will be easy for some of you but I really can't solve.

I have a json formatted like this:

{
    "id" : "1641S818",
    "balance" : "100.20",
    "transactions" : [
        {
            "id" : "item1",
            "price" : "1.50",
            "description" : "pen",
            "date" : "2018-05-14T14:19:00Z"
        },
        {
            "id" : "item1",
            "price" : "9.00",
            "description" : "book",
            "date" : "2018-05-14T08:19:00Z"
        }
    ]
}

I wanted to try and put up an app with Retrofit + Room for the first time, and I'm having trouble building models.

I came up with this data classes for Retrofit and they work fine. This is no surprise as I know how to use it.

data class Account (
    val id : String,
    val balance : Double,
    val transactions : List<Transaction>
)

data class Transaction (
    val id : String,
    val price : Double,
    val description : String,
    val date : String
)

The real issues start when I want to save this structure in a database, with this one-to-many relationship existing between the Account and the Transaction. So far I understood that Room cannot handle this type of structure and I should build different classes for the database model. So I did:

@Entity(tableName = "account")
data class AccountData(

    @ColumnInfo(name = "id")
    @PrimaryKey(autoGenerate = false)
    val id: String,

    val balance: Double,

)

@Entity(
    tableName = "transaction",
    foreignKeys = [
        ForeignKey(
            entity = AccountData::class,
            parentColumns = ["id"],
            childColumns = ["account_id"],
            onUpdate = ForeignKey.CASCADE,
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class TransactionData(

    @PrimaryKey(autoGenerate = false)
    @ColumnInfo(name = "id")
    val transactionId: String,

    @ColumnInfo(name = "account_id")
    val accountId: String,

    val price: Double,

    val description: String,

    val date: String

)

Now the part where I'm stuck. I cannot find a guide, an example, anything that shows where to convert the models with a mapper (maybe using livedata or rx) with this particular case, which is when we have complex relations between objects and not just plain classes.

Upvotes: 3

Views: 2013

Answers (1)

Ufkoku
Ufkoku

Reputation: 2638

You can define separate Mapper file with extension functions like this

fun Transaction.toTransactionData() = TransactionData(...)

And then after API call, probably in UseCase, you can use this function to map your API entity to DB entity and then pass result to Room dao.

UPD 1. Additionally you can define Transation entity for UI usage. So at UseCase level you operate with RestTransaction and DbTransaction, but passing Transaction to UI, to abstract from its source.

Upvotes: 2

Related Questions