sea_orm/entity/
active_model.rs

1use super::{ActiveValue, ActiveValue::*};
2use crate::{
3    ColumnTrait, Condition, ConnectionTrait, DbBackend, DeleteResult, EntityName, EntityTrait,
4    IdenStatic, Iterable, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter,
5    Related, RelatedSelfVia, RelationDef, RelationTrait, Value,
6    error::*,
7    query::{
8        clear_key_on_active_model, column_tuple_in_condition, get_key_from_active_model,
9        set_key_on_active_model,
10    },
11};
12use sea_query::ValueTuple;
13use std::fmt::Debug;
14
15/// `ActiveModel` is a type for constructing `INSERT` and `UPDATE` statements for a particular table.
16///
17/// Like [Model][ModelTrait], it represents a database record and each field represents a column.
18///
19/// But unlike [Model][ModelTrait], it also stores [additional state][ActiveValue] for every field,
20/// and fields are not guaranteed to have a value.
21///
22/// This allows you to:
23///
24/// - omit columns from the query,
25/// - know which columns have changed after editing a record.
26pub trait ActiveModelTrait: Clone + Debug {
27    /// The Entity this ActiveModel belongs to
28    type Entity: EntityTrait;
29
30    /// Get a mutable [ActiveValue] from an ActiveModel
31    fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;
32
33    /// Get a immutable [ActiveValue] from an ActiveModel
34    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;
35
36    /// Set the Value of a ActiveModel field, panic if failed
37    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {
38        self.try_set(c, v)
39            .unwrap_or_else(|e| panic!("Failed to set value for {:?}: {e:?}", c.as_column_ref()))
40    }
41
42    /// Set the Value of a ActiveModel field if value is different, panic if failed
43    fn set_if_not_equals(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value);
44
45    /// Set the Value of a ActiveModel field, return error if failed
46    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;
47
48    /// Set the state of an [ActiveValue] to the not set state
49    fn not_set(&mut self, c: <Self::Entity as EntityTrait>::Column);
50
51    /// Check the state of a [ActiveValue]
52    fn is_not_set(&self, c: <Self::Entity as EntityTrait>::Column) -> bool;
53
54    /// Create an ActiveModel with all fields to NotSet
55    fn default() -> Self;
56
57    /// Create an ActiveModel with all fields to Set(default_value) if Default is implemented, NotSet otherwise
58    fn default_values() -> Self;
59
60    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],
61    /// leaving [ActiveValue::NotSet] untouched.
62    fn reset(&mut self, c: <Self::Entity as EntityTrait>::Column);
63
64    /// Reset all values from [ActiveValue::Unchanged] to [ActiveValue::Set],
65    /// leaving [ActiveValue::NotSet] untouched.
66    fn reset_all(mut self) -> Self {
67        for col in <Self::Entity as EntityTrait>::Column::iter() {
68            self.reset(col);
69        }
70        self
71    }
72
73    /// Get the primary key of the ActiveModel, only if it's fully specified.
74    fn get_primary_key_value(&self) -> Option<ValueTuple> {
75        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();
76        macro_rules! next {
77            () => {
78                self.get(cols.next()?.into_column()).into_value()?
79            };
80        }
81        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {
82            1 => {
83                let s1 = next!();
84                Some(ValueTuple::One(s1))
85            }
86            2 => {
87                let s1 = next!();
88                let s2 = next!();
89                Some(ValueTuple::Two(s1, s2))
90            }
91            3 => {
92                let s1 = next!();
93                let s2 = next!();
94                let s3 = next!();
95                Some(ValueTuple::Three(s1, s2, s3))
96            }
97            len => {
98                let mut vec = Vec::with_capacity(len);
99                for _ in 0..len {
100                    let s = next!();
101                    vec.push(s);
102                }
103                Some(ValueTuple::Many(vec))
104            }
105        }
106    }
107
108    /// Perform an `INSERT` operation on the ActiveModel
109    ///
110    /// # Example (Postgres)
111    ///
112    /// ```
113    /// # use sea_orm::{error::*, tests_cfg::*, *};
114    /// #
115    /// # #[cfg(feature = "mock")]
116    /// # pub fn main() -> Result<(), DbErr> {
117    /// #
118    /// # let db = MockDatabase::new(DbBackend::Postgres)
119    /// #     .append_query_results([
120    /// #         [cake::Model {
121    /// #             id: 15,
122    /// #             name: "Apple Pie".to_owned(),
123    /// #         }],
124    /// #     ])
125    /// #     .into_connection();
126    /// #
127    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
128    ///
129    /// let apple = cake::ActiveModel {
130    ///     name: Set("Apple Pie".to_owned()),
131    ///     ..Default::default()
132    /// };
133    ///
134    /// assert_eq!(
135    ///     apple.insert(&db)?,
136    ///     cake::Model {
137    ///         id: 15,
138    ///         name: "Apple Pie".to_owned(),
139    ///     }
140    /// );
141    ///
142    /// assert_eq!(
143    ///     db.into_transaction_log(),
144    ///     [Transaction::from_sql_and_values(
145    ///         DbBackend::Postgres,
146    ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#,
147    ///         ["Apple Pie".into()]
148    ///     )]
149    /// );
150    /// #
151    /// # Ok(())
152    /// # }
153    /// ```
154    ///
155    /// # Example (MySQL)
156    ///
157    /// ```
158    /// # use sea_orm::{error::*, tests_cfg::*, *};
159    /// #
160    /// # #[cfg(feature = "mock")]
161    /// # pub fn main() -> Result<(), DbErr> {
162    /// #
163    /// # let db = MockDatabase::new(DbBackend::MySql)
164    /// #     .append_query_results([
165    /// #         [cake::Model {
166    /// #             id: 15,
167    /// #             name: "Apple Pie".to_owned(),
168    /// #         }],
169    /// #     ])
170    /// #     .append_exec_results([
171    /// #         MockExecResult {
172    /// #             last_insert_id: 15,
173    /// #             rows_affected: 1,
174    /// #         },
175    /// #     ])
176    /// #     .into_connection();
177    /// #
178    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
179    ///
180    /// let apple = cake::ActiveModel {
181    ///     name: Set("Apple Pie".to_owned()),
182    ///     ..Default::default()
183    /// };
184    ///
185    /// assert_eq!(
186    ///     apple.insert(&db)?,
187    ///     cake::Model {
188    ///         id: 15,
189    ///         name: "Apple Pie".to_owned(),
190    ///     }
191    /// );
192    ///
193    /// assert_eq!(
194    ///     db.into_transaction_log(),
195    ///     [
196    ///         Transaction::from_sql_and_values(
197    ///             DbBackend::MySql,
198    ///             r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
199    ///             ["Apple Pie".into()]
200    ///         ),
201    ///         Transaction::from_sql_and_values(
202    ///             DbBackend::MySql,
203    ///             r#"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?"#,
204    ///             [15.into(), 1u64.into()]
205    ///         )
206    ///     ]
207    /// );
208    /// #
209    /// # Ok(())
210    /// # }
211    /// ```
212    fn insert<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
213    where
214        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
215        Self: ActiveModelBehavior,
216        C: ConnectionTrait,
217    {
218        let am = ActiveModelBehavior::before_save(self, db, true)?;
219        let model = <Self::Entity as EntityTrait>::insert(am).exec_with_returning(db)?;
220        Self::after_save(model, db, true)
221    }
222
223    /// Perform the `UPDATE` operation on an ActiveModel
224    ///
225    /// # Example (Postgres)
226    ///
227    /// ```
228    /// # use sea_orm::{error::*, tests_cfg::*, *};
229    /// #
230    /// # #[cfg(feature = "mock")]
231    /// # pub fn main() -> Result<(), DbErr> {
232    /// #
233    /// # let db = MockDatabase::new(DbBackend::Postgres)
234    /// #     .append_query_results([
235    /// #         [fruit::Model {
236    /// #             id: 1,
237    /// #             name: "Orange".to_owned(),
238    /// #             cake_id: None,
239    /// #         }],
240    /// #     ])
241    /// #     .into_connection();
242    /// #
243    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
244    ///
245    /// let orange = fruit::ActiveModel {
246    ///     id: Set(1),
247    ///     name: Set("Orange".to_owned()),
248    ///     ..Default::default()
249    /// };
250    ///
251    /// assert_eq!(
252    ///     orange.update(&db)?,
253    ///     fruit::Model {
254    ///         id: 1,
255    ///         name: "Orange".to_owned(),
256    ///         cake_id: None,
257    ///     }
258    /// );
259    ///
260    /// assert_eq!(
261    ///     db.into_transaction_log(),
262    ///     [Transaction::from_sql_and_values(
263    ///         DbBackend::Postgres,
264    ///         r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 RETURNING "id", "name", "cake_id""#,
265    ///         ["Orange".into(), 1i32.into()]
266    ///     )]);
267    /// #
268    /// # Ok(())
269    /// # }
270    /// ```
271    ///
272    /// # Example (MySQL)
273    ///
274    /// ```
275    /// # use sea_orm::{error::*, tests_cfg::*, *};
276    /// #
277    /// # #[cfg(feature = "mock")]
278    /// # pub fn main() -> Result<(), DbErr> {
279    /// #
280    /// # let db = MockDatabase::new(DbBackend::MySql)
281    /// #     .append_query_results([
282    /// #         [fruit::Model {
283    /// #             id: 1,
284    /// #             name: "Orange".to_owned(),
285    /// #             cake_id: None,
286    /// #         }],
287    /// #     ])
288    /// #     .append_exec_results([
289    /// #         MockExecResult {
290    /// #             last_insert_id: 0,
291    /// #             rows_affected: 1,
292    /// #         },
293    /// #     ])
294    /// #     .into_connection();
295    /// #
296    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
297    ///
298    /// let orange = fruit::ActiveModel {
299    ///     id: Set(1),
300    ///     name: Set("Orange".to_owned()),
301    ///     ..Default::default()
302    /// };
303    ///
304    /// assert_eq!(
305    ///     orange.update(&db)?,
306    ///     fruit::Model {
307    ///         id: 1,
308    ///         name: "Orange".to_owned(),
309    ///         cake_id: None,
310    ///     }
311    /// );
312    ///
313    /// assert_eq!(
314    ///     db.into_transaction_log(),
315    ///     [
316    ///         Transaction::from_sql_and_values(
317    ///             DbBackend::MySql,
318    ///             r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?"#,
319    ///             ["Orange".into(), 1i32.into()]
320    ///         ),
321    ///         Transaction::from_sql_and_values(
322    ///             DbBackend::MySql,
323    ///             r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
324    ///             [1i32.into(), 1u64.into()]
325    ///         )]);
326    /// #
327    /// # Ok(())
328    /// # }
329    /// ```
330    fn update<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
331    where
332        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
333        Self: ActiveModelBehavior,
334        C: ConnectionTrait,
335    {
336        let am = ActiveModelBehavior::before_save(self, db, false)?;
337        let model: <Self::Entity as EntityTrait>::Model = Self::Entity::update(am).exec(db)?;
338        Self::after_save(model, db, false)
339    }
340
341    /// Insert the model if primary key is `NotSet`, update otherwise.
342    /// Only works if the entity has auto increment primary key.
343    fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
344    where
345        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
346        Self: ActiveModelBehavior,
347        C: ConnectionTrait,
348    {
349        let res = if !self.is_update() {
350            self.insert(db)
351        } else {
352            self.update(db)
353        }?;
354        Ok(res.into_active_model())
355    }
356
357    /// Returns true if the primary key is fully-specified
358    #[doc(hidden)]
359    fn is_update(&self) -> bool {
360        let mut is_update = true;
361        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {
362            let col = key.into_column();
363            if self.is_not_set(col) {
364                is_update = false;
365                break;
366            }
367        }
368        is_update
369    }
370
371    /// Delete an active model by its primary key
372    ///
373    /// # Example
374    ///
375    /// ```
376    /// # use sea_orm::{error::*, tests_cfg::*, *};
377    /// #
378    /// # #[cfg(feature = "mock")]
379    /// # pub fn main() -> Result<(), DbErr> {
380    /// #
381    /// # let db = MockDatabase::new(DbBackend::Postgres)
382    /// #     .append_exec_results([
383    /// #         MockExecResult {
384    /// #             last_insert_id: 0,
385    /// #             rows_affected: 1,
386    /// #         },
387    /// #     ])
388    /// #     .into_connection();
389    /// #
390    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
391    ///
392    /// let orange = fruit::ActiveModel {
393    ///     id: Set(3),
394    ///     ..Default::default()
395    /// };
396    ///
397    /// let delete_result = orange.delete(&db)?;
398    ///
399    /// assert_eq!(delete_result.rows_affected, 1);
400    ///
401    /// assert_eq!(
402    ///     db.into_transaction_log(),
403    ///     [Transaction::from_sql_and_values(
404    ///         DbBackend::Postgres,
405    ///         r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
406    ///         [3i32.into()]
407    ///     )]
408    /// );
409    /// #
410    /// # Ok(())
411    /// # }
412    /// ```
413    fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
414    where
415        Self: ActiveModelBehavior,
416        C: ConnectionTrait,
417    {
418        let am = ActiveModelBehavior::before_delete(self, db)?;
419        let am_clone = am.clone();
420        let delete_res = Self::Entity::delete(am).exec(db)?;
421        ActiveModelBehavior::after_delete(am_clone, db)?;
422        Ok(delete_res)
423    }
424
425    /// Set the corresponding attributes in the ActiveModel from a JSON value
426    ///
427    /// Note that this method will not alter the primary key values in ActiveModel.
428    #[cfg(feature = "with-json")]
429    fn set_from_json(&mut self, json: serde_json::Value) -> Result<(), DbErr>
430    where
431        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,
432        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
433        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:
434            serde::de::Deserialize<'de> + serde::Serialize,
435    {
436        use crate::Iterable;
437
438        // Backup primary key values
439        let primary_key_values: Vec<(<Self::Entity as EntityTrait>::Column, ActiveValue<Value>)> =
440            <<Self::Entity as EntityTrait>::PrimaryKey>::iter()
441                .map(|pk| (pk.into_column(), self.take(pk.into_column())))
442                .collect();
443
444        // Replace all values in ActiveModel
445        *self = Self::from_json(json)?;
446
447        // Restore primary key values
448        for (col, active_value) in primary_key_values {
449            match active_value {
450                ActiveValue::Unchanged(v) | ActiveValue::Set(v) => self.set(col, v),
451                NotSet => self.not_set(col),
452            }
453        }
454
455        Ok(())
456    }
457
458    /// Create ActiveModel from a JSON value
459    #[cfg(feature = "with-json")]
460    fn from_json(mut json: serde_json::Value) -> Result<Self, DbErr>
461    where
462        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,
463        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
464        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:
465            serde::de::Deserialize<'de> + serde::Serialize,
466    {
467        use crate::{IdenStatic, Iterable};
468
469        let serde_json::Value::Object(obj) = &json else {
470            return Err(DbErr::Json(format!(
471                "invalid type: expected JSON object for {}",
472                <<Self as ActiveModelTrait>::Entity as IdenStatic>::as_str(&Default::default())
473            )));
474        };
475
476        // Mark down which attribute exists in the JSON object
477        let mut json_keys: Vec<(<Self::Entity as EntityTrait>::Column, bool)> = Vec::new();
478
479        for col in <<Self::Entity as EntityTrait>::Column>::iter() {
480            let key = col.json_key();
481            let has_key = obj.contains_key(key);
482            json_keys.push((col, has_key));
483        }
484
485        // Create dummy model with dummy values
486        let dummy_model = Self::default_values();
487        if let Ok(dummy_model) = dummy_model.try_into_model() {
488            if let Ok(mut dummy_json) = serde_json::to_value(&dummy_model) {
489                let serde_json::Value::Object(merged) = &mut dummy_json else {
490                    unreachable!();
491                };
492                let serde_json::Value::Object(obj) = json else {
493                    unreachable!();
494                };
495                // overwrite dummy values with input values
496                for (key, value) in obj {
497                    merged.insert(key, value);
498                }
499                json = dummy_json;
500            }
501        }
502
503        // Convert JSON object into ActiveModel via Model
504        let model: <Self::Entity as EntityTrait>::Model =
505            serde_json::from_value(json).map_err(json_err)?;
506        let mut am = model.into_active_model();
507
508        // Transform attribute that exists in JSON object into ActiveValue::Set, otherwise ActiveValue::NotSet
509        for (col, json_key_exists) in json_keys {
510            match (json_key_exists, am.get(col)) {
511                (true, ActiveValue::Set(value) | ActiveValue::Unchanged(value)) => {
512                    am.set(col, value);
513                }
514                _ => {
515                    am.not_set(col);
516                }
517            }
518        }
519
520        Ok(am)
521    }
522
523    /// Return `true` if any attribute of `ActiveModel` is `Set`
524    fn is_changed(&self) -> bool {
525        <Self::Entity as EntityTrait>::Column::iter()
526            .any(|col| matches!(self.get(col), ActiveValue::Set(_)))
527    }
528
529    #[doc(hidden)]
530    /// Set the key to parent's key value for a belongs to relation.
531    fn set_parent_key<R, AM>(&mut self, model: &AM) -> Result<(), DbErr>
532    where
533        R: EntityTrait,
534        AM: ActiveModelTrait<Entity = R>,
535        Self::Entity: Related<R>,
536    {
537        let rel_def = Self::Entity::to();
538
539        if rel_def.is_owner {
540            return Err(DbErr::Type(format!(
541                "Relation from {} to {} is not belongs_to",
542                <Self::Entity as Default>::default().as_str(),
543                <R as Default>::default().as_str()
544            )));
545        }
546
547        let values = get_key_from_active_model(&rel_def.to_col, model)?;
548
549        set_key_on_active_model(&rel_def.from_col, self, values)?;
550
551        Ok(())
552    }
553
554    #[doc(hidden)]
555    fn set_parent_key_for<R, AM>(
556        &mut self,
557        model: &AM,
558        rel: <Self::Entity as EntityTrait>::Relation,
559    ) -> Result<(), DbErr>
560    where
561        R: EntityTrait,
562        AM: ActiveModelTrait<Entity = R>,
563    {
564        let rel_def = rel.def();
565
566        if rel_def.is_owner {
567            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
568        }
569
570        let values = get_key_from_active_model(&rel_def.to_col, model)?;
571
572        set_key_on_active_model(&rel_def.from_col, self, values)?;
573
574        Ok(())
575    }
576
577    #[doc(hidden)]
578    fn set_parent_key_for_def<R, AM>(
579        &mut self,
580        model: &AM,
581        rel_def: &RelationDef,
582    ) -> Result<(), DbErr>
583    where
584        R: EntityTrait,
585        AM: ActiveModelTrait<Entity = R>,
586    {
587        if rel_def.is_owner {
588            return Err(DbErr::Type(format!(
589                "Relation {rel_def:?} is not belongs_to"
590            )));
591        }
592
593        let values = get_key_from_active_model(&rel_def.to_col, model)?;
594
595        set_key_on_active_model(&rel_def.from_col, self, values)?;
596
597        Ok(())
598    }
599
600    #[doc(hidden)]
601    fn set_parent_key_for_self_rev<AM>(
602        &mut self,
603        model: &AM,
604        rel: <Self::Entity as EntityTrait>::Relation,
605    ) -> Result<(), DbErr>
606    where
607        AM: ActiveModelTrait<Entity = Self::Entity>,
608    {
609        let rel_def = rel.def();
610
611        if !rel_def.is_owner {
612            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
613        }
614
615        let values = get_key_from_active_model(&rel_def.from_col, model)?;
616
617        set_key_on_active_model(&rel_def.to_col, self, values)?;
618
619        Ok(())
620    }
621
622    #[doc(hidden)]
623    /// Clear parent association if the relation is optional and return true
624    fn clear_parent_key<R>(&mut self) -> Result<bool, DbErr>
625    where
626        R: EntityTrait,
627        Self::Entity: Related<R>,
628    {
629        let rel_def = Self::Entity::to();
630
631        if rel_def.is_owner {
632            return Err(DbErr::Type(format!(
633                "Relation from {} to {} is not belongs_to",
634                <Self::Entity as Default>::default().as_str(),
635                <R as Default>::default().as_str()
636            )));
637        }
638
639        clear_key_on_active_model(&rel_def.from_col, self)
640    }
641
642    #[doc(hidden)]
643    fn clear_parent_key_for_self_rev(
644        &mut self,
645        rel: <Self::Entity as EntityTrait>::Relation,
646    ) -> Result<bool, DbErr> {
647        let rel_def = rel.def();
648
649        if !rel_def.is_owner {
650            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
651        }
652
653        clear_key_on_active_model(&rel_def.to_col, self)
654    }
655
656    #[doc(hidden)]
657    /// Get the key value of belongs to relation
658    fn get_parent_key<R>(&self) -> Result<ValueTuple, DbErr>
659    where
660        R: EntityTrait,
661        Self::Entity: Related<R>,
662    {
663        let rel_def = Self::Entity::to();
664
665        if rel_def.is_owner {
666            return Err(DbErr::Type(format!(
667                "Relation from {} to {} is not belongs_to",
668                <Self::Entity as Default>::default().as_str(),
669                <R as Default>::default().as_str()
670            )));
671        }
672
673        get_key_from_active_model(&rel_def.from_col, self)
674    }
675
676    #[doc(hidden)]
677    /// Get the key value of belongs to relation
678    fn get_parent_key_for(
679        &self,
680        rel: <Self::Entity as EntityTrait>::Relation,
681    ) -> Result<ValueTuple, DbErr> {
682        let rel_def = rel.def();
683
684        if rel_def.is_owner {
685            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
686        }
687
688        get_key_from_active_model(&rel_def.from_col, self)
689    }
690
691    #[doc(hidden)]
692    fn find_belongs_to_self(
693        &self,
694        rel: <Self::Entity as EntityTrait>::Relation,
695    ) -> Result<crate::query::Select<Self::Entity>, DbErr> {
696        let rel_def = rel.def();
697
698        if !rel_def.is_owner {
699            return Err(DbErr::Type(format!(
700                "Relation {rel:?} is not has_one / has_many"
701            )));
702        }
703
704        let id = get_key_from_active_model(&rel_def.from_col, self)?;
705
706        Ok(Self::Entity::find().filter(
707            column_tuple_in_condition(
708                &<Self::Entity as Default>::default().table_ref(),
709                &rel_def.to_col,
710                &[id],
711                DbBackend::Sqlite,
712            )
713            .expect(""),
714        ))
715    }
716
717    #[doc(hidden)]
718    fn find_belongs_to_model<AM>(
719        rel_def: &RelationDef,
720        belongs_to: &AM,
721    ) -> Result<crate::query::Select<Self::Entity>, DbErr>
722    where
723        AM: ActiveModelTrait,
724    {
725        if rel_def.is_owner {
726            return Err(DbErr::Type(format!(
727                "Relation {rel_def:?} is not belongs_to"
728            )));
729        }
730
731        let id = get_key_from_active_model(&rel_def.to_col, belongs_to)?;
732        Ok(<Self::Entity as EntityTrait>::find().filter(
733            column_tuple_in_condition(
734                &rel_def.from_tbl,
735                &rel_def.from_col,
736                &[id],
737                DbBackend::Sqlite,
738            )
739            .expect(""),
740        ))
741    }
742
743    /// Find related Models belonging to self
744    fn find_related<R>(&self, _: R) -> crate::query::Select<R>
745    where
746        R: EntityTrait,
747        Self::Entity: Related<R>,
748    {
749        Self::Entity::find_related().belongs_to_active_model(self)
750    }
751
752    #[doc(hidden)]
753    fn find_related_of<AM>(&self, _: &[AM]) -> crate::query::Select<AM::Entity>
754    where
755        AM: ActiveModelTrait,
756        Self::Entity: Related<AM::Entity>,
757    {
758        self.find_related(AM::Entity::default())
759    }
760
761    /// Establish links between self and a related Entity for a many-to-many relation.
762    /// New associations will be added, and leftovers can be optionally deleted.
763    #[doc(hidden)]
764    fn establish_links<J, R, RM, C>(
765        &self,
766        _: J,
767        related_models: &[RM],
768        delete_leftover: bool,
769        db: &C,
770    ) -> Result<(), DbErr>
771    where
772        R: EntityTrait,
773        RM: ActiveModelTrait<Entity = R>,
774        J: EntityTrait + Related<R> + Related<Self::Entity>,
775        J::Model: IntoActiveModel<J::ActiveModel>,
776        J::ActiveModel: ActiveModelBehavior,
777        C: ConnectionTrait,
778    {
779        let left = <J as Related<Self::Entity>>::to();
780        let right = <J as Related<R>>::to();
781
782        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
783    }
784
785    #[doc(hidden)]
786    fn establish_links_self<J, RM, C>(
787        &self,
788        _: J,
789        related_models: &[RM],
790        delete_leftover: bool,
791        db: &C,
792    ) -> Result<(), DbErr>
793    where
794        RM: ActiveModelTrait<Entity = Self::Entity>,
795        J: EntityTrait,
796        J::Model: IntoActiveModel<J::ActiveModel>,
797        J::ActiveModel: ActiveModelBehavior,
798        C: ConnectionTrait,
799        Self::Entity: RelatedSelfVia<J>,
800    {
801        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
802        let right = <Self::Entity as RelatedSelfVia<J>>::to();
803
804        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
805    }
806
807    #[doc(hidden)]
808    fn establish_links_self_rev<J, RM, C>(
809        &self,
810        _: J,
811        related_models: &[RM],
812        delete_leftover: bool,
813        db: &C,
814    ) -> Result<(), DbErr>
815    where
816        RM: ActiveModelTrait<Entity = Self::Entity>,
817        J: EntityTrait,
818        J::Model: IntoActiveModel<J::ActiveModel>,
819        J::ActiveModel: ActiveModelBehavior,
820        C: ConnectionTrait,
821        Self::Entity: RelatedSelfVia<J>,
822    {
823        let left = <Self::Entity as RelatedSelfVia<J>>::to();
824        let right = <Self::Entity as RelatedSelfVia<J>>::via().rev();
825
826        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
827    }
828
829    #[doc(hidden)]
830    fn delete_links<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
831    where
832        J: EntityTrait + Related<Self::Entity>,
833        C: ConnectionTrait,
834    {
835        let rel_def = <J as Related<Self::Entity>>::to();
836        let id = get_key_from_active_model(&rel_def.to_col, self)?;
837
838        J::delete_many()
839            .filter(
840                column_tuple_in_condition(
841                    &rel_def.from_tbl,
842                    &rel_def.from_col,
843                    &[id],
844                    DbBackend::Sqlite,
845                )
846                .expect(""),
847            )
848            .exec(db)
849    }
850
851    #[doc(hidden)]
852    fn delete_links_self<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
853    where
854        J: EntityTrait,
855        C: ConnectionTrait,
856        Self::Entity: RelatedSelfVia<J>,
857    {
858        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
859        let right = <Self::Entity as RelatedSelfVia<J>>::to();
860
861        let id = get_key_from_active_model(&left.to_col, self)?;
862
863        if left.to_col != right.to_col {
864            return Err(DbErr::Type("Expect Self Referencing Relation".into()));
865        }
866
867        J::delete_many()
868            .filter(
869                Condition::any()
870                    .add(
871                        column_tuple_in_condition(
872                            &left.from_tbl,
873                            &left.from_col,
874                            std::slice::from_ref(&id),
875                            DbBackend::Sqlite,
876                        )
877                        .expect(""),
878                    )
879                    .add(
880                        column_tuple_in_condition(
881                            &right.from_tbl,
882                            &right.from_col,
883                            std::slice::from_ref(&id),
884                            DbBackend::Sqlite,
885                        )
886                        .expect(""),
887                    ),
888            )
889            .exec(db)
890    }
891}
892
893/// A Trait for overriding the ActiveModel behavior
894///
895/// ### Example
896/// ```ignore
897/// use sea_orm::entity::prelude::*;
898///
899///  // Use [DeriveEntity] to derive the EntityTrait automatically
900/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
901/// pub struct Entity;
902///
903/// /// The [EntityName] describes the name of a table
904/// impl EntityName for Entity {
905///     fn table_name(&self) -> &'static str {
906///         "cake"
907///     }
908/// }
909///
910/// // Derive the ActiveModel
911/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
912/// pub struct Model {
913///     pub id: i32,
914///     pub name: String,
915/// }
916///
917/// impl ActiveModelBehavior for ActiveModel {}
918/// ```
919/// See module level docs [crate::entity] for a full example
920#[allow(unused_variables)]
921pub trait ActiveModelBehavior: ActiveModelTrait {
922    /// Create a new ActiveModel with default values. This is also called by `Default::default()`.
923    ///
924    /// You can override it like the following:
925    ///
926    /// ```ignore
927    /// fn new() -> Self {
928    ///     Self {
929    ///         status: Set(Status::New),
930    ///         ..ActiveModelTrait::default()
931    ///     }
932    /// }
933    /// ```
934    fn new() -> Self {
935        <Self as ActiveModelTrait>::default()
936    }
937
938    /// Will be called before `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
939    fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
940    where
941        C: ConnectionTrait,
942    {
943        Ok(self)
944    }
945
946    /// Will be called after `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
947    fn after_save<C>(
948        model: <Self::Entity as EntityTrait>::Model,
949        db: &C,
950        insert: bool,
951    ) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
952    where
953        C: ConnectionTrait,
954    {
955        Ok(model)
956    }
957
958    /// Will be called before `ActiveModel::delete`
959    fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>
960    where
961        C: ConnectionTrait,
962    {
963        Ok(self)
964    }
965
966    /// Will be called after `ActiveModel::delete`
967    fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>
968    where
969        C: ConnectionTrait,
970    {
971        Ok(self)
972    }
973}
974
975/// A Trait for any type that can be converted into an ActiveModel
976pub trait IntoActiveModel<A>
977where
978    A: ActiveModelTrait,
979{
980    /// Method to call to perform the conversion
981    fn into_active_model(self) -> A;
982}
983
984impl<A> IntoActiveModel<A> for A
985where
986    A: ActiveModelTrait,
987{
988    fn into_active_model(self) -> A {
989        self
990    }
991}
992
993fn establish_links<EM, J, RM, C>(
994    model: &EM,
995    related_models: &[RM],
996    left: RelationDef,
997    right: RelationDef,
998    delete_leftover: bool,
999    db: &C,
1000) -> Result<(), DbErr>
1001where
1002    EM: ActiveModelTrait,
1003    RM: ActiveModelTrait,
1004    J: EntityTrait,
1005    J::Model: IntoActiveModel<J::ActiveModel>,
1006    J::ActiveModel: ActiveModelBehavior,
1007    C: ConnectionTrait,
1008{
1009    let mut require_leftover = true;
1010
1011    if related_models.is_empty() {
1012        // if there are no related models, then there is no risk of insert conflict
1013        require_leftover = false;
1014    }
1015
1016    let primary_key = J::primary_key_identity();
1017    if require_leftover
1018        && primary_key.fully_contains(&left.from_col)
1019        && primary_key.fully_contains(&right.from_col)
1020    {
1021        // if the primary key is a composite key of the two relations
1022        // we can use on conflict no action safely
1023        require_leftover = false;
1024    }
1025
1026    let mut leftover = Vec::new();
1027    if delete_leftover || require_leftover {
1028        for item in
1029            <J::ActiveModel as ActiveModelTrait>::find_belongs_to_model(&left, model)?.all(db)?
1030        {
1031            let item = item.into_active_model();
1032            let key = get_key_from_active_model(&right.from_col, &item)?;
1033            leftover.push((item, key));
1034        }
1035    }
1036    let leftover = leftover; // un-mut
1037
1038    let mut via_models = Vec::new();
1039    let mut all_keys = std::collections::HashSet::new();
1040
1041    for related_model in related_models {
1042        let mut via: J::ActiveModel = ActiveModelBehavior::new();
1043        via.set_parent_key_for_def(model, &left)?;
1044        via.set_parent_key_for_def(related_model, &right)?;
1045        let via_key = get_key_from_active_model(&right.from_col, &via)?;
1046        if !leftover.iter().any(|t| t.1 == via_key) {
1047            // if not already exist, save for insert
1048            via_models.push(via);
1049        }
1050        if delete_leftover {
1051            all_keys.insert(via_key);
1052        }
1053    }
1054
1055    if delete_leftover {
1056        let mut to_delete = Vec::new();
1057        for (leftover, key) in leftover {
1058            if !all_keys.contains(&key) {
1059                to_delete.push(
1060                    leftover
1061                        .get_primary_key_value()
1062                        .expect("item is a full model"),
1063                );
1064            }
1065        }
1066        if !to_delete.is_empty() {
1067            J::delete_many()
1068                .filter_by_value_tuples(&to_delete)
1069                .exec(db)?;
1070        }
1071    }
1072
1073    if !via_models.is_empty() {
1074        // insert new junctions
1075        J::insert_many(via_models)
1076            .on_conflict_do_nothing()
1077            .exec(db)?;
1078    }
1079
1080    Ok(())
1081}
1082
1083#[cfg(test)]
1084mod tests {
1085    use crate::{DbErr, entity::*, tests_cfg::*};
1086    use pretty_assertions::assert_eq;
1087
1088    #[cfg(feature = "with-json")]
1089    use serde_json::json;
1090
1091    #[test]
1092    #[cfg(feature = "macros")]
1093    fn test_derive_into_active_model_1() {
1094        mod my_fruit {
1095            pub use super::fruit::*;
1096            use crate as sea_orm;
1097            use crate::entity::prelude::*;
1098
1099            #[derive(DeriveIntoActiveModel)]
1100            pub struct NewFruit {
1101                // id is omitted
1102                pub name: String,
1103                // it is required as opposed to optional in Model
1104                pub cake_id: i32,
1105            }
1106        }
1107
1108        assert_eq!(
1109            my_fruit::NewFruit {
1110                name: "Apple".to_owned(),
1111                cake_id: 1,
1112            }
1113            .into_active_model(),
1114            fruit::ActiveModel {
1115                id: NotSet,
1116                name: Set("Apple".to_owned()),
1117                cake_id: Set(Some(1)),
1118            }
1119        );
1120    }
1121
1122    #[test]
1123    #[cfg(feature = "macros")]
1124    fn test_derive_into_active_model_2() {
1125        use crate as sea_orm;
1126        use crate::entity::prelude::*;
1127
1128        #[derive(DeriveIntoActiveModel)]
1129        #[sea_orm(active_model = "fruit::ActiveModel")]
1130        struct FruitName {
1131            name: String,
1132        }
1133
1134        assert_eq!(
1135            FruitName {
1136                name: "Apple Pie".to_owned(),
1137            }
1138            .into_active_model(),
1139            fruit::ActiveModel {
1140                id: NotSet,
1141                name: Set("Apple Pie".to_owned()),
1142                cake_id: NotSet,
1143            }
1144        );
1145
1146        #[derive(DeriveIntoActiveModel)]
1147        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1148        struct FruitCake {
1149            cake_id: Option<Option<i32>>,
1150        }
1151
1152        assert_eq!(
1153            FruitCake {
1154                cake_id: Some(Some(1)),
1155            }
1156            .into_active_model(),
1157            fruit::ActiveModel {
1158                id: NotSet,
1159                name: NotSet,
1160                cake_id: Set(Some(1)),
1161            }
1162        );
1163
1164        assert_eq!(
1165            FruitCake {
1166                cake_id: Some(None),
1167            }
1168            .into_active_model(),
1169            fruit::ActiveModel {
1170                id: NotSet,
1171                name: NotSet,
1172                cake_id: Set(None),
1173            }
1174        );
1175
1176        assert_eq!(
1177            FruitCake { cake_id: None }.into_active_model(),
1178            fruit::ActiveModel {
1179                id: NotSet,
1180                name: NotSet,
1181                cake_id: NotSet,
1182            }
1183        );
1184    }
1185
1186    #[test]
1187    #[cfg(feature = "macros")]
1188    fn test_derive_try_into_model_1() {
1189        mod my_fruit {
1190            use crate as sea_orm;
1191            use crate::entity::prelude::*;
1192
1193            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1194            #[sea_orm(table_name = "fruit")]
1195            pub struct Model {
1196                #[sea_orm(primary_key)]
1197                pub id: i32,
1198                pub name: String,
1199                pub cake_id: Option<i32>,
1200            }
1201
1202            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1203            pub enum Relation {}
1204
1205            impl ActiveModelBehavior for ActiveModel {}
1206        }
1207        assert_eq!(
1208            my_fruit::ActiveModel {
1209                id: Set(1),
1210                name: Set("Pineapple".to_owned()),
1211                cake_id: Set(None),
1212            }
1213            .try_into_model()
1214            .unwrap(),
1215            my_fruit::Model {
1216                id: 1,
1217                name: "Pineapple".to_owned(),
1218                cake_id: None,
1219            }
1220        );
1221
1222        assert_eq!(
1223            my_fruit::ActiveModel {
1224                id: Set(2),
1225                name: Set("Apple".to_owned()),
1226                cake_id: Set(Some(1)),
1227            }
1228            .try_into_model()
1229            .unwrap(),
1230            my_fruit::Model {
1231                id: 2,
1232                name: "Apple".to_owned(),
1233                cake_id: Some(1),
1234            }
1235        );
1236
1237        assert_eq!(
1238            my_fruit::ActiveModel {
1239                id: Set(1),
1240                name: NotSet,
1241                cake_id: Set(None),
1242            }
1243            .try_into_model(),
1244            Err(DbErr::AttrNotSet(String::from("name")))
1245        );
1246
1247        assert_eq!(
1248            my_fruit::ActiveModel {
1249                id: Set(1),
1250                name: Set("Pineapple".to_owned()),
1251                cake_id: NotSet,
1252            }
1253            .try_into_model(),
1254            Err(DbErr::AttrNotSet(String::from("cake_id")))
1255        );
1256    }
1257
1258    #[test]
1259    #[cfg(feature = "macros")]
1260    fn test_derive_try_into_model_2() {
1261        mod my_fruit {
1262            use crate as sea_orm;
1263            use crate::entity::prelude::*;
1264
1265            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1266            #[sea_orm(table_name = "fruit")]
1267            pub struct Model {
1268                #[sea_orm(primary_key)]
1269                pub id: i32,
1270                pub name: String,
1271                #[sea_orm(ignore)]
1272                pub cake_id: Option<i32>,
1273            }
1274
1275            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1276            pub enum Relation {}
1277
1278            impl ActiveModelBehavior for ActiveModel {}
1279        }
1280        assert_eq!(
1281            my_fruit::ActiveModel {
1282                id: Set(1),
1283                name: Set("Pineapple".to_owned()),
1284            }
1285            .try_into_model()
1286            .unwrap(),
1287            my_fruit::Model {
1288                id: 1,
1289                name: "Pineapple".to_owned(),
1290                cake_id: None,
1291            }
1292        );
1293    }
1294
1295    #[test]
1296    #[cfg(feature = "macros")]
1297    fn test_derive_try_into_model_3() {
1298        mod my_fruit {
1299            use crate as sea_orm;
1300            use crate::entity::prelude::*;
1301
1302            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1303            #[sea_orm(table_name = "fruit")]
1304            pub struct Model {
1305                #[sea_orm(primary_key)]
1306                pub id: i32,
1307                #[sea_orm(ignore)]
1308                pub name: String,
1309                pub cake_id: Option<i32>,
1310            }
1311
1312            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1313            pub enum Relation {}
1314
1315            impl ActiveModelBehavior for ActiveModel {}
1316        }
1317        assert_eq!(
1318            my_fruit::ActiveModel {
1319                id: Set(1),
1320                cake_id: Set(Some(1)),
1321            }
1322            .try_into_model()
1323            .unwrap(),
1324            my_fruit::Model {
1325                id: 1,
1326                name: "".to_owned(),
1327                cake_id: Some(1),
1328            }
1329        );
1330    }
1331
1332    #[test]
1333    #[cfg(feature = "with-json")]
1334    fn test_active_model_set_from_json_1() {
1335        assert_eq!(
1336            cake::ActiveModel::from_json(json!({
1337                "id": 1,
1338                "name": "Apple Pie",
1339            }))
1340            .unwrap(),
1341            cake::ActiveModel {
1342                id: Set(1),
1343                name: Set("Apple Pie".to_owned()),
1344            }
1345        );
1346
1347        assert_eq!(
1348            cake::ActiveModel::from_json(json!({
1349                "id": 1,
1350            }))
1351            .unwrap(),
1352            cake::ActiveModel {
1353                id: Set(1),
1354                name: NotSet,
1355            }
1356        );
1357
1358        assert_eq!(
1359            cake::ActiveModel::from_json(json!({
1360                "name": "Apple Pie",
1361            }))
1362            .unwrap(),
1363            cake::ActiveModel {
1364                id: NotSet,
1365                name: Set("Apple Pie".to_owned()),
1366            }
1367        );
1368
1369        let mut cake: cake::ActiveModel = Default::default();
1370        cake.set_from_json(json!({
1371            "name": "Apple Pie",
1372        }))
1373        .unwrap();
1374        assert_eq!(
1375            cake,
1376            cake::ActiveModel {
1377                id: NotSet,
1378                name: Set("Apple Pie".to_owned()),
1379            }
1380        );
1381    }
1382
1383    #[test]
1384    #[cfg(feature = "with-json")]
1385    fn test_active_model_set_from_json_2() -> Result<(), DbErr> {
1386        let mut fruit: fruit::ActiveModel = Default::default();
1387
1388        fruit.set_from_json(json!({
1389            "name": "Apple",
1390        }))?;
1391        assert_eq!(
1392            fruit,
1393            fruit::ActiveModel {
1394                id: ActiveValue::NotSet,
1395                name: ActiveValue::Set("Apple".to_owned()),
1396                cake_id: ActiveValue::NotSet,
1397            }
1398        );
1399
1400        assert_eq!(
1401            fruit::ActiveModel::from_json(json!({
1402                "name": "Apple",
1403            }))?,
1404            fruit::ActiveModel {
1405                id: ActiveValue::NotSet,
1406                name: ActiveValue::Set("Apple".to_owned()),
1407                cake_id: ActiveValue::NotSet,
1408            }
1409        );
1410
1411        fruit.set_from_json(json!({
1412            "name": "Apple",
1413            "cake_id": null,
1414        }))?;
1415        assert_eq!(
1416            fruit,
1417            fruit::ActiveModel {
1418                id: ActiveValue::NotSet,
1419                name: ActiveValue::Set("Apple".to_owned()),
1420                cake_id: ActiveValue::Set(None),
1421            }
1422        );
1423
1424        fruit.set_from_json(json!({
1425            "id": null,
1426            "name": "Apple",
1427            "cake_id": 1,
1428        }))?;
1429        assert_eq!(
1430            fruit,
1431            fruit::ActiveModel {
1432                id: ActiveValue::NotSet,
1433                name: ActiveValue::Set("Apple".to_owned()),
1434                cake_id: ActiveValue::Set(Some(1)),
1435            }
1436        );
1437
1438        fruit.set_from_json(json!({
1439            "id": 2,
1440            "name": "Apple",
1441            "cake_id": 1,
1442        }))?;
1443        assert_eq!(
1444            fruit,
1445            fruit::ActiveModel {
1446                id: ActiveValue::NotSet,
1447                name: ActiveValue::Set("Apple".to_owned()),
1448                cake_id: ActiveValue::Set(Some(1)),
1449            }
1450        );
1451
1452        let mut fruit = fruit::ActiveModel {
1453            id: ActiveValue::Set(1),
1454            name: ActiveValue::NotSet,
1455            cake_id: ActiveValue::NotSet,
1456        };
1457        fruit.set_from_json(json!({
1458            "id": 8,
1459            "name": "Apple",
1460            "cake_id": 1,
1461        }))?;
1462        assert_eq!(
1463            fruit,
1464            fruit::ActiveModel {
1465                id: ActiveValue::Set(1),
1466                name: ActiveValue::Set("Apple".to_owned()),
1467                cake_id: ActiveValue::Set(Some(1)),
1468            }
1469        );
1470
1471        Ok(())
1472    }
1473
1474    #[test]
1475    #[cfg(feature = "with-json")]
1476    fn test_active_model_set_from_json_3() -> Result<(), DbErr> {
1477        use crate::*;
1478
1479        let db = MockDatabase::new(DbBackend::Postgres)
1480            .append_exec_results([
1481                MockExecResult {
1482                    last_insert_id: 1,
1483                    rows_affected: 1,
1484                },
1485                MockExecResult {
1486                    last_insert_id: 1,
1487                    rows_affected: 1,
1488                },
1489            ])
1490            .append_query_results([
1491                [fruit::Model {
1492                    id: 1,
1493                    name: "Apple".to_owned(),
1494                    cake_id: None,
1495                }],
1496                [fruit::Model {
1497                    id: 2,
1498                    name: "Orange".to_owned(),
1499                    cake_id: Some(1),
1500                }],
1501            ])
1502            .into_connection();
1503
1504        let mut fruit: fruit::ActiveModel = Default::default();
1505        fruit.set_from_json(json!({
1506            "name": "Apple",
1507        }))?;
1508        fruit.save(&db)?;
1509
1510        let mut fruit = fruit::ActiveModel {
1511            id: Set(2),
1512            ..Default::default()
1513        };
1514        fruit.set_from_json(json!({
1515            "id": 9,
1516            "name": "Orange",
1517            "cake_id": 1,
1518        }))?;
1519        fruit.save(&db)?;
1520
1521        assert_eq!(
1522            db.into_transaction_log(),
1523            [
1524                Transaction::from_sql_and_values(
1525                    DbBackend::Postgres,
1526                    r#"INSERT INTO "fruit" ("name") VALUES ($1) RETURNING "id", "name", "cake_id""#,
1527                    ["Apple".into()],
1528                ),
1529                Transaction::from_sql_and_values(
1530                    DbBackend::Postgres,
1531                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
1532                    ["Orange".into(), 1i32.into(), 2i32.into()],
1533                ),
1534            ]
1535        );
1536
1537        Ok(())
1538    }
1539
1540    #[test]
1541    fn test_active_model_is_changed() {
1542        let mut fruit: fruit::ActiveModel = Default::default();
1543        assert!(!fruit.is_changed());
1544
1545        fruit.set(fruit::Column::Name, "apple".into());
1546        assert!(fruit.is_changed());
1547
1548        let mut fruit = fruit::Model {
1549            id: 1,
1550            name: "".into(),
1551            cake_id: None,
1552        };
1553        fruit.set("name".parse().unwrap(), "orange".into());
1554        assert_eq!(fruit.name, "orange");
1555    }
1556
1557    #[test]
1558    fn test_reset_1() {
1559        assert_eq!(
1560            fruit::Model {
1561                id: 1,
1562                name: "Apple".into(),
1563                cake_id: None,
1564            }
1565            .into_active_model(),
1566            fruit::ActiveModel {
1567                id: Unchanged(1),
1568                name: Unchanged("Apple".into()),
1569                cake_id: Unchanged(None)
1570            },
1571        );
1572
1573        assert_eq!(
1574            fruit::Model {
1575                id: 1,
1576                name: "Apple".into(),
1577                cake_id: None,
1578            }
1579            .into_active_model()
1580            .reset_all(),
1581            fruit::ActiveModel {
1582                id: Set(1),
1583                name: Set("Apple".into()),
1584                cake_id: Set(None)
1585            },
1586        );
1587
1588        assert_eq!(
1589            fruit::Model {
1590                id: 1,
1591                name: "Apple".into(),
1592                cake_id: Some(2),
1593            }
1594            .into_active_model(),
1595            fruit::ActiveModel {
1596                id: Unchanged(1),
1597                name: Unchanged("Apple".into()),
1598                cake_id: Unchanged(Some(2)),
1599            },
1600        );
1601
1602        assert_eq!(
1603            fruit::Model {
1604                id: 1,
1605                name: "Apple".into(),
1606                cake_id: Some(2),
1607            }
1608            .into_active_model()
1609            .reset_all(),
1610            fruit::ActiveModel {
1611                id: Set(1),
1612                name: Set("Apple".into()),
1613                cake_id: Set(Some(2)),
1614            },
1615        );
1616    }
1617
1618    #[test]
1619    fn test_reset_2() -> Result<(), DbErr> {
1620        use crate::*;
1621
1622        let db = MockDatabase::new(DbBackend::Postgres)
1623            .append_exec_results(vec![
1624                MockExecResult {
1625                    last_insert_id: 1,
1626                    rows_affected: 1,
1627                },
1628                MockExecResult {
1629                    last_insert_id: 1,
1630                    rows_affected: 1,
1631                },
1632            ])
1633            .append_query_results(vec![
1634                vec![fruit::Model {
1635                    id: 1,
1636                    name: "Apple".to_owned(),
1637                    cake_id: None,
1638                }],
1639                vec![fruit::Model {
1640                    id: 1,
1641                    name: "Apple".to_owned(),
1642                    cake_id: None,
1643                }],
1644            ])
1645            .into_connection();
1646
1647        fruit::Model {
1648            id: 1,
1649            name: "Apple".into(),
1650            cake_id: None,
1651        }
1652        .into_active_model()
1653        .update(&db)?;
1654
1655        fruit::Model {
1656            id: 1,
1657            name: "Apple".into(),
1658            cake_id: None,
1659        }
1660        .into_active_model()
1661        .reset_all()
1662        .update(&db)?;
1663
1664        assert_eq!(
1665            db.into_transaction_log(),
1666            vec![
1667                Transaction::from_sql_and_values(
1668                    DbBackend::Postgres,
1669                    r#"SELECT "fruit"."id", "fruit"."name", "fruit"."cake_id" FROM "fruit" WHERE "fruit"."id" = $1 LIMIT $2"#,
1670                    vec![1i32.into(), 1u64.into()],
1671                ),
1672                Transaction::from_sql_and_values(
1673                    DbBackend::Postgres,
1674                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
1675                    vec!["Apple".into(), Option::<i32>::None.into(), 1i32.into()],
1676                ),
1677            ]
1678        );
1679
1680        Ok(())
1681    }
1682
1683    #[test]
1684    fn test_active_model_default_values() {
1685        assert_eq!(
1686            fruit::ActiveModel::default_values(),
1687            fruit::ActiveModel {
1688                id: Set(0),
1689                name: Set("".into()),
1690                cake_id: Set(None),
1691            },
1692        );
1693
1694        assert_eq!(
1695            lunch_set::ActiveModel::default_values(),
1696            lunch_set::ActiveModel {
1697                id: Set(0),
1698                name: Set("".into()),
1699                tea: NotSet,
1700            },
1701        );
1702    }
1703
1704    #[test]
1705    fn test_active_model_set_parent_key() {
1706        let mut fruit = fruit::Model {
1707            id: 2,
1708            name: "F".into(),
1709            cake_id: None,
1710        }
1711        .into_active_model();
1712
1713        let cake = cake::Model {
1714            id: 4,
1715            name: "C".into(),
1716        }
1717        .into_active_model();
1718
1719        fruit.set_parent_key(&cake).unwrap();
1720
1721        assert_eq!(
1722            fruit,
1723            fruit::ActiveModel {
1724                id: Unchanged(2),
1725                name: Unchanged("F".into()),
1726                cake_id: Set(Some(4)),
1727            }
1728        );
1729
1730        assert!(fruit.clear_parent_key::<cake::Entity>().unwrap());
1731
1732        assert_eq!(
1733            fruit,
1734            fruit::ActiveModel {
1735                id: Unchanged(2),
1736                name: Unchanged("F".into()),
1737                cake_id: Set(None),
1738            }
1739        );
1740
1741        let mut cake_filling = cake_filling::ActiveModel::new();
1742
1743        cake_filling.set_parent_key(&cake).unwrap();
1744
1745        assert_eq!(
1746            cake_filling,
1747            cake_filling::ActiveModel {
1748                cake_id: Set(4),
1749                filling_id: NotSet,
1750            }
1751        );
1752    }
1753}