| 518 | /// Create ActiveModel from a JSON value |
| 519 | #[cfg(feature = "with-json")] |
| 520 | fn from_json(json: serde_json::Value) -> Result<Self, DbErr> |
| 521 | where |
| 522 | <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>, |
| 523 | for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: |
| 524 | serde::de::Deserialize<'de>, |
| 525 | { |
| 526 | use crate::{IdenStatic, Iterable}; |
| 527 | |
| 528 | let serde_json::Value::Object(obj) = &json else { |
| 529 | return Err(DbErr::Json(format!( |
| 530 | "invalid type: expected JSON object for {}", |
| 531 | <<Self as ActiveModelTrait>::Entity as IdenStatic>::as_str(&Default::default()) |
| 532 | ))); |
| 533 | }; |
| 534 | |
| 535 | // Mark down which attribute exists in the JSON object |
| 536 | let mut json_keys: Vec<(<Self::Entity as EntityTrait>::Column, bool)> = Vec::new(); |
| 537 | |
| 538 | for col in <<Self::Entity as EntityTrait>::Column>::iter() { |
| 539 | let key = col.as_str(); |
| 540 | let has_key = obj.contains_key(key); |
| 541 | json_keys.push((col, has_key)); |
| 542 | } |
| 543 | |
| 544 | // Convert JSON object into ActiveModel via Model |
| 545 | let model: <Self::Entity as EntityTrait>::Model = |
| 546 | serde_json::from_value(json).map_err(json_err)?; |
| 547 | let mut am = model.into_active_model(); |
| 548 | |
| 549 | // Transform attribute that exists in JSON object into ActiveValue::Set, otherwise ActiveValue::NotSet |
| 550 | for (col, json_key_exists) in json_keys { |
| 551 | match (json_key_exists, am.get(col)) { |
| 552 | (true, ActiveValue::Set(value) | ActiveValue::Unchanged(value)) => { |
| 553 | am.set(col, value); |
| 554 | } |
| 555 | _ => { |
| 556 | am.not_set(col); |
| 557 | } |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | Ok(am) |
| 562 | } |
| 563 | |
| 564 | /// Return `true` if any attribute of `ActiveModel` is `Set` |
| 565 | fn is_changed(&self) -> bool { |