Skip to main content

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.
26#[async_trait::async_trait]
27pub trait ActiveModelTrait: Clone + Debug {
28    /// The Entity this ActiveModel belongs to
29    type Entity: EntityTrait;
30
31    /// Get a mutable [ActiveValue] from an ActiveModel
32    fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;
33
34    /// Get a immutable [ActiveValue] from an ActiveModel
35    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;
36
37    /// Set the Value of a ActiveModel field, panic if failed
38    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {
39        self.try_set(c, v)
40            .unwrap_or_else(|e| panic!("Failed to set value for {:?}: {e:?}", c.as_column_ref()))
41    }
42
43    /// Set the Value of a ActiveModel field if value is different, panic if failed
44    fn set_if_not_equals(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value);
45
46    /// Set the Value of a ActiveModel field, return error if failed
47    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;
48
49    /// Set the state of an [ActiveValue] to the not set state
50    fn not_set(&mut self, c: <Self::Entity as EntityTrait>::Column);
51
52    /// Check the state of a [ActiveValue]
53    fn is_not_set(&self, c: <Self::Entity as EntityTrait>::Column) -> bool;
54
55    /// Create an ActiveModel with all fields to NotSet
56    fn default() -> Self;
57
58    /// Create an ActiveModel with all fields to Set(default_value) if Default is implemented, NotSet otherwise
59    fn default_values() -> Self;
60
61    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],
62    /// leaving [ActiveValue::NotSet] untouched.
63    fn reset(&mut self, c: <Self::Entity as EntityTrait>::Column);
64
65    /// Reset all values from [ActiveValue::Unchanged] to [ActiveValue::Set],
66    /// leaving [ActiveValue::NotSet] untouched.
67    fn reset_all(mut self) -> Self {
68        for col in <Self::Entity as EntityTrait>::Column::iter() {
69            self.reset(col);
70        }
71        self
72    }
73
74    /// Get the primary key of the ActiveModel, only if it's fully specified.
75    fn get_primary_key_value(&self) -> Option<ValueTuple> {
76        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();
77        macro_rules! next {
78            () => {
79                self.get(cols.next()?.into_column()).into_value()?
80            };
81        }
82        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {
83            1 => {
84                let s1 = next!();
85                Some(ValueTuple::One(s1))
86            }
87            2 => {
88                let s1 = next!();
89                let s2 = next!();
90                Some(ValueTuple::Two(s1, s2))
91            }
92            3 => {
93                let s1 = next!();
94                let s2 = next!();
95                let s3 = next!();
96                Some(ValueTuple::Three(s1, s2, s3))
97            }
98            len => {
99                let mut vec = Vec::with_capacity(len);
100                for _ in 0..len {
101                    let s = next!();
102                    vec.push(s);
103                }
104                Some(ValueTuple::Many(vec))
105            }
106        }
107    }
108
109    /// Perform an `INSERT` operation on the ActiveModel
110    ///
111    /// # Example (Postgres)
112    ///
113    /// ```
114    /// # use sea_orm::{error::*, tests_cfg::*, *};
115    /// #
116    /// # #[smol_potat::main]
117    /// # #[cfg(feature = "mock")]
118    /// # pub async fn main() -> Result<(), DbErr> {
119    /// #
120    /// # let db = MockDatabase::new(DbBackend::Postgres)
121    /// #     .append_query_results([
122    /// #         [cake::Model {
123    /// #             id: 15,
124    /// #             name: "Apple Pie".to_owned(),
125    /// #         }],
126    /// #     ])
127    /// #     .into_connection();
128    /// #
129    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
130    ///
131    /// let apple = cake::ActiveModel {
132    ///     name: Set("Apple Pie".to_owned()),
133    ///     ..Default::default()
134    /// };
135    ///
136    /// assert_eq!(
137    ///     apple.insert(&db).await?,
138    ///     cake::Model {
139    ///         id: 15,
140    ///         name: "Apple Pie".to_owned(),
141    ///     }
142    /// );
143    ///
144    /// assert_eq!(
145    ///     db.into_transaction_log(),
146    ///     [Transaction::from_sql_and_values(
147    ///         DbBackend::Postgres,
148    ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#,
149    ///         ["Apple Pie".into()]
150    ///     )]
151    /// );
152    /// #
153    /// # Ok(())
154    /// # }
155    /// ```
156    ///
157    /// # Example (MySQL)
158    ///
159    /// ```
160    /// # use sea_orm::{error::*, tests_cfg::*, *};
161    /// #
162    /// # #[smol_potat::main]
163    /// # #[cfg(feature = "mock")]
164    /// # pub async fn main() -> Result<(), DbErr> {
165    /// #
166    /// # let db = MockDatabase::new(DbBackend::MySql)
167    /// #     .append_query_results([
168    /// #         [cake::Model {
169    /// #             id: 15,
170    /// #             name: "Apple Pie".to_owned(),
171    /// #         }],
172    /// #     ])
173    /// #     .append_exec_results([
174    /// #         MockExecResult {
175    /// #             last_insert_id: 15,
176    /// #             rows_affected: 1,
177    /// #         },
178    /// #     ])
179    /// #     .into_connection();
180    /// #
181    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
182    ///
183    /// let apple = cake::ActiveModel {
184    ///     name: Set("Apple Pie".to_owned()),
185    ///     ..Default::default()
186    /// };
187    ///
188    /// assert_eq!(
189    ///     apple.insert(&db).await?,
190    ///     cake::Model {
191    ///         id: 15,
192    ///         name: "Apple Pie".to_owned(),
193    ///     }
194    /// );
195    ///
196    /// assert_eq!(
197    ///     db.into_transaction_log(),
198    ///     [
199    ///         Transaction::from_sql_and_values(
200    ///             DbBackend::MySql,
201    ///             r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
202    ///             ["Apple Pie".into()]
203    ///         ),
204    ///         Transaction::from_sql_and_values(
205    ///             DbBackend::MySql,
206    ///             r#"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?"#,
207    ///             [15.into(), 1u64.into()]
208    ///         )
209    ///     ]
210    /// );
211    /// #
212    /// # Ok(())
213    /// # }
214    /// ```
215    async fn insert<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
216    where
217        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
218        Self: ActiveModelBehavior,
219        C: ConnectionTrait,
220    {
221        let am = ActiveModelBehavior::before_save(self, db, true).await?;
222        let model = <Self::Entity as EntityTrait>::insert(am)
223            .exec_with_returning(db)
224            .await?;
225        Self::after_save(model, db, true).await
226    }
227
228    /// Perform the `UPDATE` operation on an ActiveModel
229    ///
230    /// # Example (Postgres)
231    ///
232    /// ```
233    /// # use sea_orm::{error::*, tests_cfg::*, *};
234    /// #
235    /// # #[smol_potat::main]
236    /// # #[cfg(feature = "mock")]
237    /// # pub async fn main() -> Result<(), DbErr> {
238    /// #
239    /// # let db = MockDatabase::new(DbBackend::Postgres)
240    /// #     .append_query_results([
241    /// #         [fruit::Model {
242    /// #             id: 1,
243    /// #             name: "Orange".to_owned(),
244    /// #             cake_id: None,
245    /// #         }],
246    /// #     ])
247    /// #     .into_connection();
248    /// #
249    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
250    ///
251    /// let orange = fruit::ActiveModel {
252    ///     id: Set(1),
253    ///     name: Set("Orange".to_owned()),
254    ///     ..Default::default()
255    /// };
256    ///
257    /// assert_eq!(
258    ///     orange.update(&db).await?,
259    ///     fruit::Model {
260    ///         id: 1,
261    ///         name: "Orange".to_owned(),
262    ///         cake_id: None,
263    ///     }
264    /// );
265    ///
266    /// assert_eq!(
267    ///     db.into_transaction_log(),
268    ///     [Transaction::from_sql_and_values(
269    ///         DbBackend::Postgres,
270    ///         r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 RETURNING "id", "name", "cake_id""#,
271    ///         ["Orange".into(), 1i32.into()]
272    ///     )]);
273    /// #
274    /// # Ok(())
275    /// # }
276    /// ```
277    ///
278    /// # Example (MySQL)
279    ///
280    /// ```
281    /// # use sea_orm::{error::*, tests_cfg::*, *};
282    /// #
283    /// # #[smol_potat::main]
284    /// # #[cfg(feature = "mock")]
285    /// # pub async fn main() -> Result<(), DbErr> {
286    /// #
287    /// # let db = MockDatabase::new(DbBackend::MySql)
288    /// #     .append_query_results([
289    /// #         [fruit::Model {
290    /// #             id: 1,
291    /// #             name: "Orange".to_owned(),
292    /// #             cake_id: None,
293    /// #         }],
294    /// #     ])
295    /// #     .append_exec_results([
296    /// #         MockExecResult {
297    /// #             last_insert_id: 0,
298    /// #             rows_affected: 1,
299    /// #         },
300    /// #     ])
301    /// #     .into_connection();
302    /// #
303    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
304    ///
305    /// let orange = fruit::ActiveModel {
306    ///     id: Set(1),
307    ///     name: Set("Orange".to_owned()),
308    ///     ..Default::default()
309    /// };
310    ///
311    /// assert_eq!(
312    ///     orange.update(&db).await?,
313    ///     fruit::Model {
314    ///         id: 1,
315    ///         name: "Orange".to_owned(),
316    ///         cake_id: None,
317    ///     }
318    /// );
319    ///
320    /// assert_eq!(
321    ///     db.into_transaction_log(),
322    ///     [
323    ///         Transaction::from_sql_and_values(
324    ///             DbBackend::MySql,
325    ///             r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?"#,
326    ///             ["Orange".into(), 1i32.into()]
327    ///         ),
328    ///         Transaction::from_sql_and_values(
329    ///             DbBackend::MySql,
330    ///             r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
331    ///             [1i32.into(), 1u64.into()]
332    ///         )]);
333    /// #
334    /// # Ok(())
335    /// # }
336    /// ```
337    async fn update<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
338    where
339        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
340        Self: ActiveModelBehavior,
341        C: ConnectionTrait,
342    {
343        let am = ActiveModelBehavior::before_save(self, db, false).await?;
344        let model: <Self::Entity as EntityTrait>::Model = Self::Entity::update(am).exec(db).await?;
345        Self::after_save(model, db, false).await
346    }
347
348    /// Insert the model if primary key is `NotSet`, update otherwise.
349    /// Only works if the entity has auto increment primary key.
350    async fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
351    where
352        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
353        Self: ActiveModelBehavior,
354        C: ConnectionTrait,
355    {
356        let res = if !self.is_update() {
357            self.insert(db).await
358        } else {
359            self.update(db).await
360        }?;
361        Ok(res.into_active_model())
362    }
363
364    /// Returns true if the primary key is fully-specified
365    #[doc(hidden)]
366    fn is_update(&self) -> bool {
367        let mut is_update = true;
368        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {
369            let col = key.into_column();
370            if self.is_not_set(col) {
371                is_update = false;
372                break;
373            }
374        }
375        is_update
376    }
377
378    /// Delete an active model by its primary key
379    ///
380    /// # Example
381    ///
382    /// ```
383    /// # use sea_orm::{error::*, tests_cfg::*, *};
384    /// #
385    /// # #[smol_potat::main]
386    /// # #[cfg(feature = "mock")]
387    /// # pub async fn main() -> Result<(), DbErr> {
388    /// #
389    /// # let db = MockDatabase::new(DbBackend::Postgres)
390    /// #     .append_exec_results([
391    /// #         MockExecResult {
392    /// #             last_insert_id: 0,
393    /// #             rows_affected: 1,
394    /// #         },
395    /// #     ])
396    /// #     .into_connection();
397    /// #
398    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
399    ///
400    /// let orange = fruit::ActiveModel {
401    ///     id: Set(3),
402    ///     ..Default::default()
403    /// };
404    ///
405    /// let delete_result = orange.delete(&db).await?;
406    ///
407    /// assert_eq!(delete_result.rows_affected, 1);
408    ///
409    /// assert_eq!(
410    ///     db.into_transaction_log(),
411    ///     [Transaction::from_sql_and_values(
412    ///         DbBackend::Postgres,
413    ///         r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
414    ///         [3i32.into()]
415    ///     )]
416    /// );
417    /// #
418    /// # Ok(())
419    /// # }
420    /// ```
421    async fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
422    where
423        Self: ActiveModelBehavior,
424        C: ConnectionTrait,
425    {
426        let am = ActiveModelBehavior::before_delete(self, db).await?;
427        let am_clone = am.clone();
428        let delete_res = Self::Entity::delete(am).exec(db).await?;
429        ActiveModelBehavior::after_delete(am_clone, db).await?;
430        Ok(delete_res)
431    }
432
433    /// Set the corresponding attributes in the ActiveModel from a JSON value
434    ///
435    /// Note that this method will not alter the primary key values in ActiveModel.
436    #[cfg(feature = "with-json")]
437    fn set_from_json(&mut self, json: serde_json::Value) -> Result<(), DbErr>
438    where
439        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,
440        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
441        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:
442            serde::de::Deserialize<'de> + serde::Serialize,
443    {
444        use crate::Iterable;
445
446        // Backup primary key values
447        let primary_key_values: Vec<(<Self::Entity as EntityTrait>::Column, ActiveValue<Value>)> =
448            <<Self::Entity as EntityTrait>::PrimaryKey>::iter()
449                .map(|pk| (pk.into_column(), self.take(pk.into_column())))
450                .collect();
451
452        // Replace all values in ActiveModel
453        *self = Self::from_json(json)?;
454
455        // Restore primary key values
456        for (col, active_value) in primary_key_values {
457            match active_value {
458                ActiveValue::Unchanged(v) | ActiveValue::Set(v) => self.set(col, v),
459                NotSet => self.not_set(col),
460            }
461        }
462
463        Ok(())
464    }
465
466    /// Create ActiveModel from a JSON value
467    #[cfg(feature = "with-json")]
468    fn from_json(mut json: serde_json::Value) -> Result<Self, DbErr>
469    where
470        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,
471        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
472        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:
473            serde::de::Deserialize<'de> + serde::Serialize,
474    {
475        use crate::{IdenStatic, Iterable};
476
477        let serde_json::Value::Object(obj) = &json else {
478            return Err(DbErr::Json(format!(
479                "invalid type: expected JSON object for {}",
480                <<Self as ActiveModelTrait>::Entity as IdenStatic>::as_str(&Default::default())
481            )));
482        };
483
484        // Mark down which attribute exists in the JSON object
485        let mut json_keys: Vec<(<Self::Entity as EntityTrait>::Column, bool)> = Vec::new();
486
487        for col in <<Self::Entity as EntityTrait>::Column>::iter() {
488            let key = col.json_key();
489            let has_key = obj.contains_key(key);
490            json_keys.push((col, has_key));
491        }
492
493        // Create dummy model with dummy values
494        let dummy_model = Self::default_values();
495        if let Ok(dummy_model) = dummy_model.try_into_model() {
496            if let Ok(mut dummy_json) = serde_json::to_value(&dummy_model) {
497                let serde_json::Value::Object(merged) = &mut dummy_json else {
498                    unreachable!();
499                };
500                let serde_json::Value::Object(obj) = json else {
501                    unreachable!();
502                };
503                // overwrite dummy values with input values
504                for (key, value) in obj {
505                    merged.insert(key, value);
506                }
507                json = dummy_json;
508            }
509        }
510
511        // Convert JSON object into ActiveModel via Model
512        let model: <Self::Entity as EntityTrait>::Model =
513            serde_json::from_value(json).map_err(json_err)?;
514        let mut am = model.into_active_model();
515
516        // Transform attribute that exists in JSON object into ActiveValue::Set, otherwise ActiveValue::NotSet
517        for (col, json_key_exists) in json_keys {
518            match (json_key_exists, am.get(col)) {
519                (true, ActiveValue::Set(value) | ActiveValue::Unchanged(value)) => {
520                    am.set(col, value);
521                }
522                _ => {
523                    am.not_set(col);
524                }
525            }
526        }
527
528        Ok(am)
529    }
530
531    /// Create a Vec of ActiveModels from an Arrow RecordBatch.
532    ///
533    /// Each row in the RecordBatch becomes one ActiveModel.
534    /// Columns are matched by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).
535    /// Columns present in the RecordBatch are marked as `Set`;
536    /// columns absent from the RecordBatch are marked as `NotSet`.
537    ///
538    /// Supported column types: integers (i8–i64, u8–u64), floats (f32, f64),
539    /// `String`/`Text`, `Boolean`, and date/time types (with `with-chrono` or `with-time`).
540    /// Null values in nullable columns are handled.
541    ///
542    /// When both `with-chrono` and `with-time` features are enabled, chrono values
543    /// are attempted first. If the model uses time-crate types, the conversion
544    /// automatically falls back to the time-crate representation.
545    #[cfg(feature = "with-arrow")]
546    fn from_arrow(batch: &sea_orm_arrow::arrow::array::RecordBatch) -> Result<Vec<Self>, DbErr> {
547        use crate::{IdenStatic, Iterable, with_arrow::arrow_array_to_value};
548
549        let num_rows = batch.num_rows();
550        let mut results = Vec::with_capacity(num_rows);
551
552        for row in 0..num_rows {
553            let mut am = Self::default();
554
555            for col in <<Self::Entity as EntityTrait>::Column>::iter() {
556                let col_name = col.as_str();
557
558                if let Some(arrow_col) = batch.column_by_name(col_name) {
559                    let col_def = col.def();
560                    let col_type = col_def.get_column_type();
561                    let value = arrow_array_to_value(arrow_col.as_ref(), col_type, row)?;
562
563                    // When both chrono and time features are enabled, the primary
564                    // conversion produces chrono Values for date/time columns.
565                    // If the model's field uses time-crate types, try_set will fail;
566                    // retry with the time-crate alternative.
567                    #[cfg(all(feature = "with-chrono", feature = "with-time"))]
568                    {
569                        use crate::with_arrow::{arrow_array_to_value_alt, is_datetime_column};
570                        match am.try_set(col, value) {
571                            Ok(()) => {}
572                            Err(first_err) if is_datetime_column(col_type) => {
573                                if let Some(alt_value) =
574                                    arrow_array_to_value_alt(arrow_col.as_ref(), col_type, row)?
575                                {
576                                    am.try_set(col, alt_value)?;
577                                } else {
578                                    return Err(first_err);
579                                }
580                            }
581                            Err(e) => return Err(e),
582                        }
583                    }
584
585                    #[cfg(not(all(feature = "with-chrono", feature = "with-time")))]
586                    am.try_set(col, value)?;
587                } else {
588                    am.not_set(col);
589                }
590            }
591
592            results.push(am);
593        }
594
595        Ok(results)
596    }
597
598    /// Convert a slice of ActiveModels into an Arrow [`RecordBatch`](arrow::array::RecordBatch).
599    ///
600    /// The `schema` determines the output columns: each schema field is matched
601    /// to an entity column by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).
602    /// Columns marked `Set` or `Unchanged` contribute their value;
603    /// `NotSet` columns become null in the output.
604    ///
605    /// Typical usage together with [`ArrowSchema`](crate::ArrowSchema):
606    /// ```ignore
607    /// let schema = MyEntity::arrow_schema();
608    /// let batch = MyActiveModel::to_arrow(&models, &schema)?;
609    /// ```
610    #[cfg(feature = "with-arrow")]
611    fn to_arrow(
612        models: &[Self],
613        schema: &sea_orm_arrow::arrow::datatypes::Schema,
614    ) -> Result<sea_orm_arrow::arrow::array::RecordBatch, DbErr> {
615        use crate::{Iterable, with_arrow::option_values_to_arrow_array};
616        use std::sync::Arc;
617
618        let mut columns: Vec<Arc<dyn sea_orm_arrow::arrow::array::Array>> =
619            Vec::with_capacity(schema.fields().len());
620
621        for field in schema.fields() {
622            let field_name = field.name();
623
624            // Find the entity column whose name matches this schema field
625            let entity_col =
626                <<Self::Entity as EntityTrait>::Column>::iter().find(|c| c.as_str() == field_name);
627
628            if let Some(col) = entity_col {
629                let values: Vec<Option<Value>> = models
630                    .iter()
631                    .map(|m| match m.get(col) {
632                        ActiveValue::Set(v) | ActiveValue::Unchanged(v) => Some(v),
633                        ActiveValue::NotSet => None,
634                    })
635                    .collect();
636
637                let array = option_values_to_arrow_array(&values, field.data_type())?;
638                columns.push(array);
639            } else {
640                // Field in schema but not in entity → null column
641                let array =
642                    sea_orm_arrow::arrow::array::new_null_array(field.data_type(), models.len());
643                columns.push(array);
644            }
645        }
646
647        sea_orm_arrow::arrow::array::RecordBatch::try_new(Arc::new(schema.clone()), columns)
648            .map_err(|e| DbErr::Type(format!("Failed to create RecordBatch: {e}")))
649    }
650
651    /// Return `true` if any attribute of `ActiveModel` is `Set`
652    fn is_changed(&self) -> bool {
653        <Self::Entity as EntityTrait>::Column::iter()
654            .any(|col| matches!(self.get(col), ActiveValue::Set(_)))
655    }
656
657    #[doc(hidden)]
658    /// Set the key to parent's key value for a belongs to relation.
659    fn set_parent_key<R, AM>(&mut self, model: &AM) -> Result<(), DbErr>
660    where
661        R: EntityTrait,
662        AM: ActiveModelTrait<Entity = R>,
663        Self::Entity: Related<R>,
664    {
665        let rel_def = Self::Entity::to();
666
667        if rel_def.is_owner {
668            return Err(DbErr::Type(format!(
669                "Relation from {} to {} is not belongs_to",
670                <Self::Entity as Default>::default().as_str(),
671                <R as Default>::default().as_str()
672            )));
673        }
674
675        let values = get_key_from_active_model(&rel_def.to_col, model)?;
676
677        set_key_on_active_model(&rel_def.from_col, self, values)?;
678
679        Ok(())
680    }
681
682    #[doc(hidden)]
683    fn set_parent_key_for<R, AM>(
684        &mut self,
685        model: &AM,
686        rel: <Self::Entity as EntityTrait>::Relation,
687    ) -> Result<(), DbErr>
688    where
689        R: EntityTrait,
690        AM: ActiveModelTrait<Entity = R>,
691    {
692        let rel_def = rel.def();
693
694        if rel_def.is_owner {
695            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
696        }
697
698        let values = get_key_from_active_model(&rel_def.to_col, model)?;
699
700        set_key_on_active_model(&rel_def.from_col, self, values)?;
701
702        Ok(())
703    }
704
705    #[doc(hidden)]
706    fn set_parent_key_for_def<R, AM>(
707        &mut self,
708        model: &AM,
709        rel_def: &RelationDef,
710    ) -> Result<(), DbErr>
711    where
712        R: EntityTrait,
713        AM: ActiveModelTrait<Entity = R>,
714    {
715        if rel_def.is_owner {
716            return Err(DbErr::Type(format!(
717                "Relation {rel_def:?} is not belongs_to"
718            )));
719        }
720
721        let values = get_key_from_active_model(&rel_def.to_col, model)?;
722
723        set_key_on_active_model(&rel_def.from_col, self, values)?;
724
725        Ok(())
726    }
727
728    #[doc(hidden)]
729    fn set_parent_key_for_self_rev<AM>(
730        &mut self,
731        model: &AM,
732        rel: <Self::Entity as EntityTrait>::Relation,
733    ) -> Result<(), DbErr>
734    where
735        AM: ActiveModelTrait<Entity = Self::Entity>,
736    {
737        let rel_def = rel.def();
738
739        if !rel_def.is_owner {
740            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
741        }
742
743        let values = get_key_from_active_model(&rel_def.from_col, model)?;
744
745        set_key_on_active_model(&rel_def.to_col, self, values)?;
746
747        Ok(())
748    }
749
750    #[doc(hidden)]
751    /// Clear parent association if the relation is optional and return true
752    fn clear_parent_key<R>(&mut self) -> Result<bool, DbErr>
753    where
754        R: EntityTrait,
755        Self::Entity: Related<R>,
756    {
757        let rel_def = Self::Entity::to();
758
759        if rel_def.is_owner {
760            return Err(DbErr::Type(format!(
761                "Relation from {} to {} is not belongs_to",
762                <Self::Entity as Default>::default().as_str(),
763                <R as Default>::default().as_str()
764            )));
765        }
766
767        clear_key_on_active_model(&rel_def.from_col, self)
768    }
769
770    #[doc(hidden)]
771    fn clear_parent_key_for_self_rev(
772        &mut self,
773        rel: <Self::Entity as EntityTrait>::Relation,
774    ) -> Result<bool, DbErr> {
775        let rel_def = rel.def();
776
777        if !rel_def.is_owner {
778            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
779        }
780
781        clear_key_on_active_model(&rel_def.to_col, self)
782    }
783
784    #[doc(hidden)]
785    /// Get the key value of belongs to relation
786    fn get_parent_key<R>(&self) -> Result<ValueTuple, DbErr>
787    where
788        R: EntityTrait,
789        Self::Entity: Related<R>,
790    {
791        let rel_def = Self::Entity::to();
792
793        if rel_def.is_owner {
794            return Err(DbErr::Type(format!(
795                "Relation from {} to {} is not belongs_to",
796                <Self::Entity as Default>::default().as_str(),
797                <R as Default>::default().as_str()
798            )));
799        }
800
801        get_key_from_active_model(&rel_def.from_col, self)
802    }
803
804    #[doc(hidden)]
805    /// Get the key value of belongs to relation
806    fn get_parent_key_for(
807        &self,
808        rel: <Self::Entity as EntityTrait>::Relation,
809    ) -> Result<ValueTuple, DbErr> {
810        let rel_def = rel.def();
811
812        if rel_def.is_owner {
813            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
814        }
815
816        get_key_from_active_model(&rel_def.from_col, self)
817    }
818
819    #[doc(hidden)]
820    fn find_belongs_to_self(
821        &self,
822        rel: <Self::Entity as EntityTrait>::Relation,
823        db_backend: DbBackend,
824    ) -> Result<crate::query::Select<Self::Entity>, DbErr> {
825        let rel_def = rel.def();
826
827        if !rel_def.is_owner {
828            return Err(DbErr::Type(format!(
829                "Relation {rel:?} is not has_one / has_many"
830            )));
831        }
832
833        let id = get_key_from_active_model(&rel_def.from_col, self)?;
834
835        Ok(Self::Entity::find().filter(
836            column_tuple_in_condition(
837                &<Self::Entity as Default>::default().table_ref(),
838                &rel_def.to_col,
839                &[id],
840                db_backend,
841            )
842            .expect(""),
843        ))
844    }
845
846    #[doc(hidden)]
847    fn find_belongs_to_model<AM>(
848        rel_def: &RelationDef,
849        belongs_to: &AM,
850        db_backend: DbBackend,
851    ) -> Result<crate::query::Select<Self::Entity>, DbErr>
852    where
853        AM: ActiveModelTrait,
854    {
855        if rel_def.is_owner {
856            return Err(DbErr::Type(format!(
857                "Relation {rel_def:?} is not belongs_to"
858            )));
859        }
860
861        let id = get_key_from_active_model(&rel_def.to_col, belongs_to)?;
862        Ok(<Self::Entity as EntityTrait>::find().filter(
863            column_tuple_in_condition(&rel_def.from_tbl, &rel_def.from_col, &[id], db_backend)
864                .expect(""),
865        ))
866    }
867
868    /// Find related Models belonging to self
869    fn find_related<R>(&self, _: R) -> crate::query::Select<R>
870    where
871        R: EntityTrait,
872        Self::Entity: Related<R>,
873    {
874        Self::Entity::find_related().belongs_to_active_model(self)
875    }
876
877    /// Like find_related, but infer type from `AM`
878    #[doc(hidden)]
879    fn find_related_of<AM>(&self, _: &[AM]) -> crate::query::Select<AM::Entity>
880    where
881        AM: ActiveModelTrait,
882        Self::Entity: Related<AM::Entity>,
883    {
884        self.find_related(AM::Entity::default())
885    }
886
887    /// Establish links between self and a related Entity for a many-to-many relation.
888    /// New associations will be added, and leftovers can be optionally deleted.
889    #[doc(hidden)]
890    async fn establish_links<J, R, RM, C>(
891        &self,
892        _: J,
893        related_models: &[RM],
894        delete_leftover: bool,
895        db: &C,
896    ) -> Result<(), DbErr>
897    where
898        R: EntityTrait,
899        RM: ActiveModelTrait<Entity = R> + Sync,
900        J: EntityTrait + Related<R> + Related<Self::Entity>,
901        J::Model: IntoActiveModel<J::ActiveModel>,
902        J::ActiveModel: ActiveModelBehavior + Send,
903        C: ConnectionTrait,
904    {
905        let left = <J as Related<Self::Entity>>::to();
906        let right = <J as Related<R>>::to();
907
908        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await
909    }
910
911    /// Establish links for self-referencing many-to-many relation
912    #[doc(hidden)]
913    async fn establish_links_self<J, RM, C>(
914        &self,
915        _: J,
916        related_models: &[RM],
917        delete_leftover: bool,
918        db: &C,
919    ) -> Result<(), DbErr>
920    where
921        RM: ActiveModelTrait<Entity = Self::Entity> + Sync,
922        J: EntityTrait,
923        J::Model: IntoActiveModel<J::ActiveModel>,
924        J::ActiveModel: ActiveModelBehavior + Send,
925        C: ConnectionTrait,
926        Self::Entity: RelatedSelfVia<J>,
927    {
928        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
929        let right = <Self::Entity as RelatedSelfVia<J>>::to();
930
931        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await
932    }
933
934    /// Establish links for self-referencing many-to-many relation, but left-right reversed
935    #[doc(hidden)]
936    async fn establish_links_self_rev<J, RM, C>(
937        &self,
938        _: J,
939        related_models: &[RM],
940        delete_leftover: bool,
941        db: &C,
942    ) -> Result<(), DbErr>
943    where
944        RM: ActiveModelTrait<Entity = Self::Entity> + Sync,
945        J: EntityTrait,
946        J::Model: IntoActiveModel<J::ActiveModel>,
947        J::ActiveModel: ActiveModelBehavior + Send,
948        C: ConnectionTrait,
949        Self::Entity: RelatedSelfVia<J>,
950    {
951        let left = <Self::Entity as RelatedSelfVia<J>>::to();
952        let right = <Self::Entity as RelatedSelfVia<J>>::via().rev();
953
954        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await
955    }
956
957    /// Inverse of establish link, break links between two many-to-many models
958    #[doc(hidden)]
959    async fn delete_links<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
960    where
961        J: EntityTrait + Related<Self::Entity>,
962        C: ConnectionTrait,
963    {
964        let rel_def = <J as Related<Self::Entity>>::to();
965        let id = get_key_from_active_model(&rel_def.to_col, self)?;
966
967        J::delete_many()
968            .filter(
969                column_tuple_in_condition(
970                    &rel_def.from_tbl,
971                    &rel_def.from_col,
972                    &[id],
973                    db.get_database_backend(),
974                )
975                .expect(""),
976            )
977            .exec(db)
978            .await
979    }
980
981    /// Like `delete_links` but for self-referencing relations
982    #[doc(hidden)]
983    async fn delete_links_self<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
984    where
985        J: EntityTrait,
986        C: ConnectionTrait,
987        Self::Entity: RelatedSelfVia<J>,
988    {
989        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
990        let right = <Self::Entity as RelatedSelfVia<J>>::to();
991
992        let id = get_key_from_active_model(&left.to_col, self)?;
993
994        if left.to_col != right.to_col {
995            return Err(DbErr::Type("Expect Self Referencing Relation".into()));
996        }
997
998        J::delete_many()
999            .filter(
1000                Condition::any()
1001                    .add(
1002                        column_tuple_in_condition(
1003                            &left.from_tbl,
1004                            &left.from_col,
1005                            std::slice::from_ref(&id),
1006                            db.get_database_backend(),
1007                        )
1008                        .expect(""),
1009                    )
1010                    .add(
1011                        column_tuple_in_condition(
1012                            &right.from_tbl,
1013                            &right.from_col,
1014                            std::slice::from_ref(&id),
1015                            db.get_database_backend(),
1016                        )
1017                        .expect(""),
1018                    ),
1019            )
1020            .exec(db)
1021            .await
1022    }
1023}
1024
1025/// A Trait for overriding the ActiveModel behavior
1026///
1027/// ### Example
1028/// ```ignore
1029/// use sea_orm::entity::prelude::*;
1030///
1031///  // Use [DeriveEntity] to derive the EntityTrait automatically
1032/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
1033/// pub struct Entity;
1034///
1035/// /// The [EntityName] describes the name of a table
1036/// impl EntityName for Entity {
1037///     fn table_name(&self) -> &'static str {
1038///         "cake"
1039///     }
1040/// }
1041///
1042/// // Derive the ActiveModel
1043/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
1044/// pub struct Model {
1045///     pub id: i32,
1046///     pub name: String,
1047/// }
1048///
1049/// impl ActiveModelBehavior for ActiveModel {}
1050/// ```
1051/// See module level docs [crate::entity] for a full example
1052#[allow(unused_variables)]
1053#[async_trait::async_trait]
1054pub trait ActiveModelBehavior: ActiveModelTrait {
1055    /// Create a new ActiveModel with default values. This is also called by `Default::default()`.
1056    ///
1057    /// You can override it like the following:
1058    ///
1059    /// ```ignore
1060    /// fn new() -> Self {
1061    ///     Self {
1062    ///         status: Set(Status::New),
1063    ///         ..ActiveModelTrait::default()
1064    ///     }
1065    /// }
1066    /// ```
1067    fn new() -> Self {
1068        <Self as ActiveModelTrait>::default()
1069    }
1070
1071    /// Will be called before `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
1072    async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
1073    where
1074        C: ConnectionTrait,
1075    {
1076        Ok(self)
1077    }
1078
1079    /// Will be called after `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
1080    async fn after_save<C>(
1081        model: <Self::Entity as EntityTrait>::Model,
1082        db: &C,
1083        insert: bool,
1084    ) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
1085    where
1086        C: ConnectionTrait,
1087    {
1088        Ok(model)
1089    }
1090
1091    /// Will be called before `ActiveModel::delete`
1092    async fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>
1093    where
1094        C: ConnectionTrait,
1095    {
1096        Ok(self)
1097    }
1098
1099    /// Will be called after `ActiveModel::delete`
1100    async fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>
1101    where
1102        C: ConnectionTrait,
1103    {
1104        Ok(self)
1105    }
1106}
1107
1108/// A Trait for any type that can be converted into an `ActiveModel`,
1109/// can be derived using `DeriveIntoActiveModel`.
1110///
1111/// ## Derive Macro Example
1112///
1113/// ```rust
1114/// use sea_orm::DeriveIntoActiveModel;
1115/// mod fruit {
1116///     use sea_orm::entity::prelude::*;
1117///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1118///     #[sea_orm(table_name = "fruit")]
1119///     pub struct Model {
1120///         #[sea_orm(primary_key)]
1121///         pub id: i32,
1122///         pub name: String,
1123///         pub cake_id: Option<i32>,
1124///     }
1125///     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1126///     pub enum Relation {}
1127///     impl ActiveModelBehavior for ActiveModel {}
1128/// }
1129///
1130/// #[derive(DeriveIntoActiveModel)]
1131/// #[sea_orm(active_model = "fruit::ActiveModel")]
1132/// struct NewFruit {
1133///     name: String,
1134///     // `id` and `cake_id` are omitted - they become `NotSet`
1135/// }
1136/// ```
1137///
1138/// ## `set(...)` - always set absent ActiveModel fields
1139///
1140/// ```rust
1141/// # mod fruit {
1142/// #     use sea_orm::entity::prelude::*;
1143/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1144/// #     #[sea_orm(table_name = "fruit")]
1145/// #     pub struct Model {
1146/// #         #[sea_orm(primary_key)]
1147/// #         pub id: i32,
1148/// #         pub name: String,
1149/// #         pub cake_id: Option<i32>,
1150/// #     }
1151/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1152/// #     pub enum Relation {}
1153/// #     impl ActiveModelBehavior for ActiveModel {}
1154/// # }
1155/// use sea_orm::DeriveIntoActiveModel;
1156///
1157/// #[derive(DeriveIntoActiveModel)]
1158/// #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "None"))]
1159/// struct NewFruit {
1160///     name: String,
1161///     // `cake_id` is not on the struct, but will always be `Set(None)`
1162/// }
1163/// ```
1164///
1165/// ## `default = "expr"` - fallback for `Option<T>` struct fields
1166///
1167/// ```rust
1168/// # mod fruit {
1169/// #     use sea_orm::entity::prelude::*;
1170/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1171/// #     #[sea_orm(table_name = "fruit")]
1172/// #     pub struct Model {
1173/// #         #[sea_orm(primary_key)]
1174/// #         pub id: i32,
1175/// #         pub name: String,
1176/// #         pub cake_id: Option<i32>,
1177/// #     }
1178/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1179/// #     pub enum Relation {}
1180/// #     impl ActiveModelBehavior for ActiveModel {}
1181/// # }
1182/// use sea_orm::DeriveIntoActiveModel;
1183///
1184/// #[derive(DeriveIntoActiveModel)]
1185/// #[sea_orm(active_model = "fruit::ActiveModel")]
1186/// struct UpdateFruit {
1187///     /// `Some("Apple")` -> `Set("Apple")`, `None` ->`Set("Unnamed")`
1188///     #[sea_orm(default = "String::from(\"Unnamed\")")]
1189///     name: Option<String>,
1190/// }
1191/// ```
1192pub trait IntoActiveModel<A>
1193where
1194    A: ActiveModelTrait,
1195{
1196    /// Method to call to perform the conversion
1197    fn into_active_model(self) -> A;
1198}
1199
1200impl<A> IntoActiveModel<A> for A
1201where
1202    A: ActiveModelTrait,
1203{
1204    fn into_active_model(self) -> A {
1205        self
1206    }
1207}
1208
1209async fn establish_links<EM, J, RM, C>(
1210    model: &EM,
1211    related_models: &[RM],
1212    left: RelationDef,
1213    right: RelationDef,
1214    delete_leftover: bool,
1215    db: &C,
1216) -> Result<(), DbErr>
1217where
1218    EM: ActiveModelTrait,
1219    RM: ActiveModelTrait,
1220    J: EntityTrait,
1221    J::Model: IntoActiveModel<J::ActiveModel>,
1222    J::ActiveModel: ActiveModelBehavior,
1223    C: ConnectionTrait,
1224{
1225    let mut require_leftover = true;
1226
1227    if related_models.is_empty() {
1228        // if there are no related models, then there is no risk of insert conflict
1229        require_leftover = false;
1230    }
1231
1232    let primary_key = J::primary_key_identity();
1233    if require_leftover
1234        && primary_key.fully_contains(&left.from_col)
1235        && primary_key.fully_contains(&right.from_col)
1236    {
1237        // if the primary key is a composite key of the two relations
1238        // we can use on conflict no action safely
1239        require_leftover = false;
1240    }
1241
1242    let mut leftover = Vec::new();
1243    if delete_leftover || require_leftover {
1244        for item in <J::ActiveModel as ActiveModelTrait>::find_belongs_to_model(
1245            &left,
1246            model,
1247            db.get_database_backend(),
1248        )?
1249        .all(db)
1250        .await?
1251        {
1252            let item = item.into_active_model();
1253            let key = get_key_from_active_model(&right.from_col, &item)?;
1254            leftover.push((item, key));
1255        }
1256    }
1257    let leftover = leftover; // un-mut
1258
1259    let mut via_models = Vec::new();
1260    let mut all_keys = std::collections::HashSet::new();
1261
1262    for related_model in related_models {
1263        let mut via: J::ActiveModel = ActiveModelBehavior::new();
1264        via.set_parent_key_for_def(model, &left)?;
1265        via.set_parent_key_for_def(related_model, &right)?;
1266        let via_key = get_key_from_active_model(&right.from_col, &via)?;
1267        if !leftover.iter().any(|t| t.1 == via_key) {
1268            // if not already exist, save for insert
1269            via_models.push(via);
1270        }
1271        if delete_leftover {
1272            all_keys.insert(via_key);
1273        }
1274    }
1275
1276    if delete_leftover {
1277        let mut to_delete = Vec::new();
1278        for (leftover, key) in leftover {
1279            if !all_keys.contains(&key) {
1280                to_delete.push(
1281                    leftover
1282                        .get_primary_key_value()
1283                        .expect("item is a full model"),
1284                );
1285            }
1286        }
1287        if !to_delete.is_empty() {
1288            J::delete_many()
1289                .filter_by_value_tuples(&to_delete, db.get_database_backend())
1290                .exec(db)
1291                .await?;
1292        }
1293    }
1294
1295    if !via_models.is_empty() {
1296        // insert new junctions
1297        J::insert_many(via_models)
1298            .on_conflict_do_nothing()
1299            .exec(db)
1300            .await?;
1301    }
1302
1303    Ok(())
1304}
1305
1306#[cfg(test)]
1307mod tests {
1308    use crate::{DbErr, entity::*, tests_cfg::*};
1309    use pretty_assertions::assert_eq;
1310
1311    #[cfg(feature = "with-json")]
1312    use serde_json::json;
1313
1314    #[test]
1315    #[cfg(feature = "macros")]
1316    fn test_derive_into_active_model_1() {
1317        mod my_fruit {
1318            pub use super::fruit::*;
1319            use crate as sea_orm;
1320            use crate::entity::prelude::*;
1321
1322            #[derive(DeriveIntoActiveModel)]
1323            pub struct NewFruit {
1324                // id is omitted
1325                pub name: String,
1326                // it is required as opposed to optional in Model
1327                pub cake_id: i32,
1328            }
1329        }
1330
1331        assert_eq!(
1332            my_fruit::NewFruit {
1333                name: "Apple".to_owned(),
1334                cake_id: 1,
1335            }
1336            .into_active_model(),
1337            fruit::ActiveModel {
1338                id: NotSet,
1339                name: Set("Apple".to_owned()),
1340                cake_id: Set(Some(1)),
1341            }
1342        );
1343    }
1344
1345    #[test]
1346    #[cfg(feature = "macros")]
1347    fn test_derive_into_active_model_2() {
1348        use crate as sea_orm;
1349        use crate::entity::prelude::*;
1350
1351        #[derive(DeriveIntoActiveModel)]
1352        #[sea_orm(active_model = "fruit::ActiveModel")]
1353        struct RequiredFruitName {
1354            name: String,
1355        }
1356
1357        assert_eq!(
1358            RequiredFruitName {
1359                name: "Apple Pie".to_owned(),
1360            }
1361            .into_active_model(),
1362            fruit::ActiveModel {
1363                id: NotSet,
1364                name: Set("Apple Pie".to_owned()),
1365                cake_id: NotSet,
1366            }
1367        );
1368
1369        #[derive(DeriveIntoActiveModel)]
1370        #[sea_orm(active_model = "fruit::ActiveModel")]
1371        struct OptionalFruitName {
1372            name: Option<String>,
1373        }
1374
1375        assert_eq!(
1376            OptionalFruitName {
1377                name: Some("Apple Pie".to_owned()),
1378            }
1379            .into_active_model(),
1380            fruit::ActiveModel {
1381                id: NotSet,
1382                name: Set("Apple Pie".to_owned()),
1383                cake_id: NotSet,
1384            }
1385        );
1386
1387        assert_eq!(
1388            OptionalFruitName { name: None }.into_active_model(),
1389            fruit::ActiveModel {
1390                id: NotSet,
1391                name: NotSet,
1392                cake_id: NotSet,
1393            }
1394        );
1395
1396        #[derive(DeriveIntoActiveModel)]
1397        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1398        struct RequiredAndNotNullFruitCake {
1399            cake_id: i32,
1400        }
1401
1402        assert_eq!(
1403            RequiredAndNotNullFruitCake { cake_id: 1 }.into_active_model(),
1404            fruit::ActiveModel {
1405                id: NotSet,
1406                name: NotSet,
1407                cake_id: Set(Some(1)),
1408            }
1409        );
1410
1411        #[derive(DeriveIntoActiveModel)]
1412        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1413        struct OptionalAndNotNullFruitCake {
1414            cake_id: Option<i32>,
1415        }
1416
1417        assert_eq!(
1418            OptionalAndNotNullFruitCake { cake_id: Some(1) }.into_active_model(),
1419            fruit::ActiveModel {
1420                id: NotSet,
1421                name: NotSet,
1422                cake_id: Set(Some(1)),
1423            }
1424        );
1425
1426        assert_eq!(
1427            OptionalAndNotNullFruitCake { cake_id: None }.into_active_model(),
1428            fruit::ActiveModel {
1429                id: NotSet,
1430                name: NotSet,
1431                cake_id: NotSet,
1432            }
1433        );
1434
1435        #[derive(DeriveIntoActiveModel)]
1436        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1437        struct OptionalAndNullableFruitCake {
1438            cake_id: Option<Option<i32>>,
1439        }
1440
1441        assert_eq!(
1442            OptionalAndNullableFruitCake {
1443                cake_id: Some(Some(1)),
1444            }
1445            .into_active_model(),
1446            fruit::ActiveModel {
1447                id: NotSet,
1448                name: NotSet,
1449                cake_id: Set(Some(1)),
1450            }
1451        );
1452
1453        assert_eq!(
1454            OptionalAndNullableFruitCake {
1455                cake_id: Some(None),
1456            }
1457            .into_active_model(),
1458            fruit::ActiveModel {
1459                id: NotSet,
1460                name: NotSet,
1461                cake_id: Set(None),
1462            }
1463        );
1464
1465        assert_eq!(
1466            OptionalAndNullableFruitCake { cake_id: None }.into_active_model(),
1467            fruit::ActiveModel {
1468                id: NotSet,
1469                name: NotSet,
1470                cake_id: NotSet,
1471            }
1472        );
1473    }
1474
1475    #[test]
1476    #[cfg(feature = "macros")]
1477    fn test_derive_into_active_model_set_single() {
1478        use crate as sea_orm;
1479        use crate::entity::prelude::*;
1480
1481        #[derive(DeriveIntoActiveModel)]
1482        #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "None"))]
1483        struct NewFruit {
1484            name: String,
1485        }
1486
1487        assert_eq!(
1488            NewFruit {
1489                name: "Apple".to_owned(),
1490            }
1491            .into_active_model(),
1492            fruit::ActiveModel {
1493                id: NotSet,
1494                name: Set("Apple".to_owned()),
1495                cake_id: Set(None),
1496            }
1497        );
1498    }
1499
1500    #[test]
1501    #[cfg(feature = "macros")]
1502    fn test_derive_into_active_model_set_multiple() {
1503        use crate as sea_orm;
1504        use crate::entity::prelude::*;
1505
1506        #[derive(DeriveIntoActiveModel)]
1507        #[sea_orm(
1508            active_model = "fruit::ActiveModel",
1509            set(name = "String::from(\"cherry\")", cake_id = "None")
1510        )]
1511        struct IdOnlyFruit {
1512            id: i32,
1513        }
1514        assert_eq!(
1515            IdOnlyFruit { id: 1 }.into_active_model(),
1516            fruit::ActiveModel {
1517                id: Set(1),
1518                name: Set("cherry".to_owned()),
1519                cake_id: Set(None),
1520            }
1521        );
1522
1523        #[derive(DeriveIntoActiveModel)]
1524        #[sea_orm(
1525            active_model = "fruit::ActiveModel",
1526            set(name = "String::from(\"cherry\")"),
1527            set(cake_id = "None")
1528        )]
1529        struct IdOnlyFruit2 {
1530            id: i32,
1531        }
1532        assert_eq!(
1533            IdOnlyFruit2 { id: 1 }.into_active_model(),
1534            fruit::ActiveModel {
1535                id: Set(1),
1536                name: Set("cherry".to_owned()),
1537                cake_id: Set(None),
1538            }
1539        );
1540    }
1541
1542    #[test]
1543    #[cfg(feature = "macros")]
1544    fn test_derive_into_active_model_set_separate_attrs() {
1545        use crate as sea_orm;
1546        use crate::entity::prelude::*;
1547
1548        #[derive(DeriveIntoActiveModel)]
1549        #[sea_orm(
1550            active_model = "fruit::ActiveModel",
1551            set(name = "String::from(\"cherry\")")
1552        )]
1553        #[sea_orm(set(cake_id = "None"))]
1554        struct IdOnlyFruit {
1555            id: i32,
1556        }
1557
1558        assert_eq!(
1559            IdOnlyFruit { id: 1 }.into_active_model(),
1560            fruit::ActiveModel {
1561                id: Set(1),
1562                name: Set("cherry".to_owned()),
1563                cake_id: Set(None),
1564            }
1565        );
1566    }
1567
1568    #[test]
1569    #[cfg(feature = "macros")]
1570    fn test_derive_into_active_model_ignore() {
1571        use crate as sea_orm;
1572        use crate::entity::prelude::*;
1573
1574        #[derive(DeriveIntoActiveModel)]
1575        #[sea_orm(active_model = "fruit::ActiveModel")]
1576        struct NewFruit {
1577            name: String,
1578            cake_id: i32,
1579            #[sea_orm(ignore)]
1580            _extra: String,
1581        }
1582
1583        assert_eq!(
1584            NewFruit {
1585                name: "Apple".to_owned(),
1586                cake_id: 1,
1587                _extra: "ignored".to_owned(),
1588            }
1589            .into_active_model(),
1590            fruit::ActiveModel {
1591                id: NotSet,
1592                name: Set("Apple".to_owned()),
1593                cake_id: Set(Some(1)),
1594            }
1595        );
1596    }
1597
1598    #[test]
1599    #[cfg(feature = "macros")]
1600    fn test_derive_into_active_model_skip() {
1601        use crate as sea_orm;
1602        use crate::entity::prelude::*;
1603
1604        #[derive(DeriveIntoActiveModel)]
1605        #[sea_orm(active_model = "fruit::ActiveModel")]
1606        struct NewFruit {
1607            name: String,
1608            #[sea_orm(skip)]
1609            _extra: String,
1610        }
1611
1612        assert_eq!(
1613            NewFruit {
1614                name: "Apple".to_owned(),
1615                _extra: "skipped".to_owned(),
1616            }
1617            .into_active_model(),
1618            fruit::ActiveModel {
1619                id: NotSet,
1620                name: Set("Apple".to_owned()),
1621                cake_id: NotSet,
1622            }
1623        );
1624    }
1625
1626    #[test]
1627    #[cfg(feature = "macros")]
1628    fn test_derive_into_active_model_set_and_ignore() {
1629        use crate as sea_orm;
1630        use crate::entity::prelude::*;
1631
1632        #[derive(DeriveIntoActiveModel)]
1633        #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "Some(42)"))]
1634        struct NewFruit {
1635            name: String,
1636            #[sea_orm(ignore)]
1637            _extra: String,
1638        }
1639
1640        assert_eq!(
1641            NewFruit {
1642                name: "Apple".to_owned(),
1643                _extra: "ignored".to_owned(),
1644            }
1645            .into_active_model(),
1646            fruit::ActiveModel {
1647                id: NotSet,
1648                name: Set("Apple".to_owned()),
1649                cake_id: Set(Some(42)),
1650            }
1651        );
1652    }
1653
1654    #[test]
1655    #[cfg(feature = "macros")]
1656    fn test_derive_into_active_model_foreign_ignore() {
1657        use serde::{Deserialize, Serialize};
1658
1659        use crate as sea_orm;
1660        use crate::entity::prelude::*;
1661
1662        #[derive(DeriveIntoActiveModel, Serialize, Deserialize)]
1663        #[sea_orm(active_model = "fruit::ActiveModel")]
1664        struct NewFruit {
1665            #[sea_orm(ignore)]
1666            id: i32,
1667            name: String,
1668            #[serde(skip)]
1669            cake_id: Option<i32>,
1670        }
1671
1672        assert_eq!(
1673            NewFruit {
1674                id: 1.to_owned(),
1675                name: "Apple".to_owned(),
1676                cake_id: Some(42)
1677            }
1678            .into_active_model(),
1679            fruit::ActiveModel {
1680                id: NotSet,
1681                name: Set("Apple".to_owned()),
1682                cake_id: Set(Some(42)),
1683            }
1684        );
1685    }
1686
1687    #[test]
1688    #[cfg(feature = "macros")]
1689    fn test_derive_into_active_model_exhaustive() {
1690        use crate as sea_orm;
1691        use crate::entity::prelude::*;
1692
1693        #[derive(DeriveIntoActiveModel)]
1694        #[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
1695        struct FullFruit {
1696            id: i32,
1697            name: String,
1698        }
1699
1700        assert_eq!(
1701            FullFruit {
1702                id: 1,
1703                name: "Apple".to_owned(),
1704            }
1705            .into_active_model(),
1706            fruit::ActiveModel {
1707                id: Set(1),
1708                name: Set("Apple".to_owned()),
1709                cake_id: Set(None),
1710            }
1711        );
1712    }
1713
1714    #[test]
1715    #[cfg(feature = "macros")]
1716    fn test_derive_into_active_model_multiple_sets() {
1717        use crate as sea_orm;
1718        use crate::entity::prelude::*;
1719
1720        const DEFULT_CAKE_ID: i32 = 1;
1721        #[derive(DeriveIntoActiveModel)]
1722        #[sea_orm(
1723            active_model = "fruit::ActiveModel",
1724            exhaustive,
1725            set(cake_id = "Some(DEFULT_CAKE_ID)")
1726        )]
1727        struct FullFruit {
1728            id: i32,
1729            name: String,
1730        }
1731
1732        assert_eq!(
1733            FullFruit {
1734                id: 1,
1735                name: "Apple".to_owned(),
1736            }
1737            .into_active_model(),
1738            fruit::ActiveModel {
1739                id: Set(1),
1740                name: Set("Apple".to_owned()),
1741                cake_id: Set(Some(1)),
1742            }
1743        );
1744    }
1745
1746    #[test]
1747    #[cfg(feature = "macros")]
1748    fn test_derive_into_active_model_field_empty_default() {
1749        use crate as sea_orm;
1750        use crate::entity::prelude::*;
1751
1752        #[derive(DeriveIntoActiveModel)]
1753        #[sea_orm(active_model = "fruit::ActiveModel")]
1754        struct NewFruit {
1755            #[sea_orm(default)]
1756            name: Option<String>,
1757        }
1758
1759        // Some(v) -> Set(v)
1760        assert_eq!(
1761            NewFruit {
1762                name: Some("Apple".to_owned()),
1763            }
1764            .into_active_model(),
1765            fruit::ActiveModel {
1766                id: NotSet,
1767                name: Set("Apple".to_owned()),
1768                cake_id: NotSet,
1769            }
1770        );
1771
1772        // None -> Set(fallback)
1773        assert_eq!(
1774            NewFruit { name: None }.into_active_model(),
1775            fruit::ActiveModel {
1776                id: NotSet,
1777                name: Set("".to_owned()),
1778                cake_id: NotSet,
1779            }
1780        );
1781    }
1782
1783    #[test]
1784    #[cfg(feature = "macros")]
1785    fn test_derive_into_active_model_field_custom_option() {
1786        use crate as sea_orm;
1787        use crate::entity::prelude::*;
1788        mod foreign_crate {
1789            #[derive(Debug, Clone, PartialEq, Eq)]
1790            pub enum CustomOption<T> {
1791                None,
1792                Some(T),
1793            }
1794
1795            impl From<CustomOption<String>> for Option<String> {
1796                fn from(option: CustomOption<String>) -> Self {
1797                    match option {
1798                        CustomOption::None => Option::None,
1799                        CustomOption::Some(value) => value.into(),
1800                    }
1801                }
1802            }
1803        }
1804        use foreign_crate::CustomOption;
1805
1806        #[derive(DeriveIntoActiveModel)]
1807        #[sea_orm(active_model = "fruit::ActiveModel")]
1808        struct NewFruit {
1809            #[sea_orm(default)]
1810            name: CustomOption<String>,
1811        }
1812
1813        // Some(v) -> Set(v)
1814        assert_eq!(
1815            NewFruit {
1816                name: CustomOption::Some("Apple".to_owned()),
1817            }
1818            .into_active_model(),
1819            fruit::ActiveModel {
1820                id: NotSet,
1821                name: Set("Apple".to_owned()),
1822                cake_id: NotSet,
1823            }
1824        );
1825
1826        // None -> Set(fallback)
1827        assert_eq!(
1828            NewFruit {
1829                name: CustomOption::None
1830            }
1831            .into_active_model(),
1832            fruit::ActiveModel {
1833                id: NotSet,
1834                name: Set("".to_owned()),
1835                cake_id: NotSet,
1836            }
1837        );
1838    }
1839
1840    #[test]
1841    #[cfg(feature = "macros")]
1842    fn test_derive_into_active_model_field_default_some() {
1843        use crate as sea_orm;
1844        use crate::entity::prelude::*;
1845
1846        #[derive(DeriveIntoActiveModel)]
1847        #[sea_orm(active_model = "fruit::ActiveModel")]
1848        struct NewFruit {
1849            #[sea_orm(default = "String::from(\"Unnamed\")")]
1850            name: Option<String>,
1851        }
1852
1853        // Some(v) -> Set(v)
1854        assert_eq!(
1855            NewFruit {
1856                name: Some("Apple".to_owned()),
1857            }
1858            .into_active_model(),
1859            fruit::ActiveModel {
1860                id: NotSet,
1861                name: Set("Apple".to_owned()),
1862                cake_id: NotSet,
1863            }
1864        );
1865
1866        // None -> Set(fallback)
1867        assert_eq!(
1868            NewFruit { name: None }.into_active_model(),
1869            fruit::ActiveModel {
1870                id: NotSet,
1871                name: Set("Unnamed".to_owned()),
1872                cake_id: NotSet,
1873            }
1874        );
1875    }
1876
1877    #[test]
1878    #[cfg(feature = "macros")]
1879    fn test_derive_into_active_model_field_default_with_set() {
1880        use crate as sea_orm;
1881        use crate::entity::prelude::*;
1882
1883        #[derive(DeriveIntoActiveModel)]
1884        #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "Some(99)"))]
1885        struct NewFruit {
1886            #[sea_orm(default = "String::from(\"Unnamed\")")]
1887            name: Option<String>,
1888            #[sea_orm(ignore)]
1889            _extra: String,
1890        }
1891
1892        assert_eq!(
1893            NewFruit {
1894                name: Some("Apple".to_owned()),
1895                _extra: "ignored".to_owned(),
1896            }
1897            .into_active_model(),
1898            fruit::ActiveModel {
1899                id: NotSet,
1900                name: Set("Apple".to_owned()),
1901                cake_id: Set(Some(99)),
1902            }
1903        );
1904
1905        assert_eq!(
1906            NewFruit {
1907                name: None,
1908                _extra: "ignored".to_owned(),
1909            }
1910            .into_active_model(),
1911            fruit::ActiveModel {
1912                id: NotSet,
1913                name: Set("Unnamed".to_owned()),
1914                cake_id: Set(Some(99)),
1915            }
1916        );
1917    }
1918
1919    #[test]
1920    #[cfg(feature = "macros")]
1921    fn test_derive_into_active_model_field_default_exhaustive() {
1922        use crate as sea_orm;
1923        use crate::entity::prelude::*;
1924
1925        #[derive(DeriveIntoActiveModel)]
1926        #[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
1927        struct NewFruit {
1928            id: i32,
1929            #[sea_orm(default = "String::from(\"Unnamed\")")]
1930            name: Option<String>,
1931        }
1932
1933        assert_eq!(
1934            NewFruit {
1935                id: 1,
1936                name: Some("Apple".to_owned()),
1937            }
1938            .into_active_model(),
1939            fruit::ActiveModel {
1940                id: Set(1),
1941                name: Set("Apple".to_owned()),
1942                cake_id: Set(None),
1943            }
1944        );
1945
1946        assert_eq!(
1947            NewFruit { id: 2, name: None }.into_active_model(),
1948            fruit::ActiveModel {
1949                id: Set(2),
1950                name: Set("Unnamed".to_owned()),
1951                cake_id: Set(None),
1952            }
1953        );
1954    }
1955
1956    #[test]
1957    #[cfg(feature = "macros")]
1958    fn test_derive_try_into_model_1() {
1959        mod my_fruit {
1960            use crate as sea_orm;
1961            use crate::entity::prelude::*;
1962
1963            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1964            #[sea_orm(table_name = "fruit")]
1965            pub struct Model {
1966                #[sea_orm(primary_key)]
1967                pub id: i32,
1968                pub name: String,
1969                pub cake_id: Option<i32>,
1970            }
1971
1972            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1973            pub enum Relation {}
1974
1975            impl ActiveModelBehavior for ActiveModel {}
1976        }
1977        assert_eq!(
1978            my_fruit::ActiveModel {
1979                id: Set(1),
1980                name: Set("Pineapple".to_owned()),
1981                cake_id: Set(None),
1982            }
1983            .try_into_model()
1984            .unwrap(),
1985            my_fruit::Model {
1986                id: 1,
1987                name: "Pineapple".to_owned(),
1988                cake_id: None,
1989            }
1990        );
1991
1992        assert_eq!(
1993            my_fruit::ActiveModel {
1994                id: Set(2),
1995                name: Set("Apple".to_owned()),
1996                cake_id: Set(Some(1)),
1997            }
1998            .try_into_model()
1999            .unwrap(),
2000            my_fruit::Model {
2001                id: 2,
2002                name: "Apple".to_owned(),
2003                cake_id: Some(1),
2004            }
2005        );
2006
2007        assert_eq!(
2008            my_fruit::ActiveModel {
2009                id: Set(1),
2010                name: NotSet,
2011                cake_id: Set(None),
2012            }
2013            .try_into_model(),
2014            Err(DbErr::AttrNotSet(String::from("name")))
2015        );
2016
2017        assert_eq!(
2018            my_fruit::ActiveModel {
2019                id: Set(1),
2020                name: Set("Pineapple".to_owned()),
2021                cake_id: NotSet,
2022            }
2023            .try_into_model(),
2024            Err(DbErr::AttrNotSet(String::from("cake_id")))
2025        );
2026    }
2027
2028    #[test]
2029    #[cfg(feature = "macros")]
2030    fn test_derive_try_into_model_2() {
2031        mod my_fruit {
2032            use crate as sea_orm;
2033            use crate::entity::prelude::*;
2034
2035            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
2036            #[sea_orm(table_name = "fruit")]
2037            pub struct Model {
2038                #[sea_orm(primary_key)]
2039                pub id: i32,
2040                pub name: String,
2041                #[sea_orm(ignore)]
2042                pub cake_id: Option<i32>,
2043            }
2044
2045            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
2046            pub enum Relation {}
2047
2048            impl ActiveModelBehavior for ActiveModel {}
2049        }
2050        assert_eq!(
2051            my_fruit::ActiveModel {
2052                id: Set(1),
2053                name: Set("Pineapple".to_owned()),
2054            }
2055            .try_into_model()
2056            .unwrap(),
2057            my_fruit::Model {
2058                id: 1,
2059                name: "Pineapple".to_owned(),
2060                cake_id: None,
2061            }
2062        );
2063    }
2064
2065    #[test]
2066    #[cfg(feature = "macros")]
2067    fn test_derive_try_into_model_3() {
2068        mod my_fruit {
2069            use crate as sea_orm;
2070            use crate::entity::prelude::*;
2071
2072            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
2073            #[sea_orm(table_name = "fruit")]
2074            pub struct Model {
2075                #[sea_orm(primary_key)]
2076                pub id: i32,
2077                #[sea_orm(ignore)]
2078                pub name: String,
2079                pub cake_id: Option<i32>,
2080            }
2081
2082            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
2083            pub enum Relation {}
2084
2085            impl ActiveModelBehavior for ActiveModel {}
2086        }
2087        assert_eq!(
2088            my_fruit::ActiveModel {
2089                id: Set(1),
2090                cake_id: Set(Some(1)),
2091            }
2092            .try_into_model()
2093            .unwrap(),
2094            my_fruit::Model {
2095                id: 1,
2096                name: "".to_owned(),
2097                cake_id: Some(1),
2098            }
2099        );
2100    }
2101
2102    #[test]
2103    #[cfg(feature = "with-json")]
2104    fn test_active_model_set_from_json_1() {
2105        assert_eq!(
2106            cake::ActiveModel::from_json(json!({
2107                "id": 1,
2108                "name": "Apple Pie",
2109            }))
2110            .unwrap(),
2111            cake::ActiveModel {
2112                id: Set(1),
2113                name: Set("Apple Pie".to_owned()),
2114            }
2115        );
2116
2117        assert_eq!(
2118            cake::ActiveModel::from_json(json!({
2119                "id": 1,
2120            }))
2121            .unwrap(),
2122            cake::ActiveModel {
2123                id: Set(1),
2124                name: NotSet,
2125            }
2126        );
2127
2128        assert_eq!(
2129            cake::ActiveModel::from_json(json!({
2130                "name": "Apple Pie",
2131            }))
2132            .unwrap(),
2133            cake::ActiveModel {
2134                id: NotSet,
2135                name: Set("Apple Pie".to_owned()),
2136            }
2137        );
2138
2139        let mut cake: cake::ActiveModel = Default::default();
2140        cake.set_from_json(json!({
2141            "name": "Apple Pie",
2142        }))
2143        .unwrap();
2144        assert_eq!(
2145            cake,
2146            cake::ActiveModel {
2147                id: NotSet,
2148                name: Set("Apple Pie".to_owned()),
2149            }
2150        );
2151    }
2152
2153    #[test]
2154    #[cfg(feature = "with-json")]
2155    fn test_active_model_set_from_json_2() -> Result<(), DbErr> {
2156        let mut fruit: fruit::ActiveModel = Default::default();
2157
2158        fruit.set_from_json(json!({
2159            "name": "Apple",
2160        }))?;
2161        assert_eq!(
2162            fruit,
2163            fruit::ActiveModel {
2164                id: ActiveValue::NotSet,
2165                name: ActiveValue::Set("Apple".to_owned()),
2166                cake_id: ActiveValue::NotSet,
2167            }
2168        );
2169
2170        assert_eq!(
2171            fruit::ActiveModel::from_json(json!({
2172                "name": "Apple",
2173            }))?,
2174            fruit::ActiveModel {
2175                id: ActiveValue::NotSet,
2176                name: ActiveValue::Set("Apple".to_owned()),
2177                cake_id: ActiveValue::NotSet,
2178            }
2179        );
2180
2181        fruit.set_from_json(json!({
2182            "name": "Apple",
2183            "cake_id": null,
2184        }))?;
2185        assert_eq!(
2186            fruit,
2187            fruit::ActiveModel {
2188                id: ActiveValue::NotSet,
2189                name: ActiveValue::Set("Apple".to_owned()),
2190                cake_id: ActiveValue::Set(None),
2191            }
2192        );
2193
2194        fruit.set_from_json(json!({
2195            "id": null,
2196            "name": "Apple",
2197            "cake_id": 1,
2198        }))?;
2199        assert_eq!(
2200            fruit,
2201            fruit::ActiveModel {
2202                id: ActiveValue::NotSet,
2203                name: ActiveValue::Set("Apple".to_owned()),
2204                cake_id: ActiveValue::Set(Some(1)),
2205            }
2206        );
2207
2208        fruit.set_from_json(json!({
2209            "id": 2,
2210            "name": "Apple",
2211            "cake_id": 1,
2212        }))?;
2213        assert_eq!(
2214            fruit,
2215            fruit::ActiveModel {
2216                id: ActiveValue::NotSet,
2217                name: ActiveValue::Set("Apple".to_owned()),
2218                cake_id: ActiveValue::Set(Some(1)),
2219            }
2220        );
2221
2222        let mut fruit = fruit::ActiveModel {
2223            id: ActiveValue::Set(1),
2224            name: ActiveValue::NotSet,
2225            cake_id: ActiveValue::NotSet,
2226        };
2227        fruit.set_from_json(json!({
2228            "id": 8,
2229            "name": "Apple",
2230            "cake_id": 1,
2231        }))?;
2232        assert_eq!(
2233            fruit,
2234            fruit::ActiveModel {
2235                id: ActiveValue::Set(1),
2236                name: ActiveValue::Set("Apple".to_owned()),
2237                cake_id: ActiveValue::Set(Some(1)),
2238            }
2239        );
2240
2241        Ok(())
2242    }
2243
2244    #[smol_potat::test]
2245    #[cfg(feature = "with-json")]
2246    async fn test_active_model_set_from_json_3() -> Result<(), DbErr> {
2247        use crate::*;
2248
2249        let db = MockDatabase::new(DbBackend::Postgres)
2250            .append_exec_results([
2251                MockExecResult {
2252                    last_insert_id: 1,
2253                    rows_affected: 1,
2254                },
2255                MockExecResult {
2256                    last_insert_id: 1,
2257                    rows_affected: 1,
2258                },
2259            ])
2260            .append_query_results([
2261                [fruit::Model {
2262                    id: 1,
2263                    name: "Apple".to_owned(),
2264                    cake_id: None,
2265                }],
2266                [fruit::Model {
2267                    id: 2,
2268                    name: "Orange".to_owned(),
2269                    cake_id: Some(1),
2270                }],
2271            ])
2272            .into_connection();
2273
2274        let mut fruit: fruit::ActiveModel = Default::default();
2275        fruit.set_from_json(json!({
2276            "name": "Apple",
2277        }))?;
2278        fruit.save(&db).await?;
2279
2280        let mut fruit = fruit::ActiveModel {
2281            id: Set(2),
2282            ..Default::default()
2283        };
2284        fruit.set_from_json(json!({
2285            "id": 9,
2286            "name": "Orange",
2287            "cake_id": 1,
2288        }))?;
2289        fruit.save(&db).await?;
2290
2291        assert_eq!(
2292            db.into_transaction_log(),
2293            [
2294                Transaction::from_sql_and_values(
2295                    DbBackend::Postgres,
2296                    r#"INSERT INTO "fruit" ("name") VALUES ($1) RETURNING "id", "name", "cake_id""#,
2297                    ["Apple".into()],
2298                ),
2299                Transaction::from_sql_and_values(
2300                    DbBackend::Postgres,
2301                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
2302                    ["Orange".into(), 1i32.into(), 2i32.into()],
2303                ),
2304            ]
2305        );
2306
2307        Ok(())
2308    }
2309
2310    #[test]
2311    fn test_active_model_is_changed() {
2312        let mut fruit: fruit::ActiveModel = Default::default();
2313        assert!(!fruit.is_changed());
2314
2315        fruit.set(fruit::Column::Name, "apple".into());
2316        assert!(fruit.is_changed());
2317
2318        let mut fruit = fruit::Model {
2319            id: 1,
2320            name: "".into(),
2321            cake_id: None,
2322        };
2323        fruit.set("name".parse().unwrap(), "orange".into());
2324        assert_eq!(fruit.name, "orange");
2325    }
2326
2327    #[test]
2328    fn test_reset_1() {
2329        assert_eq!(
2330            fruit::Model {
2331                id: 1,
2332                name: "Apple".into(),
2333                cake_id: None,
2334            }
2335            .into_active_model(),
2336            fruit::ActiveModel {
2337                id: Unchanged(1),
2338                name: Unchanged("Apple".into()),
2339                cake_id: Unchanged(None)
2340            },
2341        );
2342
2343        assert_eq!(
2344            fruit::Model {
2345                id: 1,
2346                name: "Apple".into(),
2347                cake_id: None,
2348            }
2349            .into_active_model()
2350            .reset_all(),
2351            fruit::ActiveModel {
2352                id: Set(1),
2353                name: Set("Apple".into()),
2354                cake_id: Set(None)
2355            },
2356        );
2357
2358        assert_eq!(
2359            fruit::Model {
2360                id: 1,
2361                name: "Apple".into(),
2362                cake_id: Some(2),
2363            }
2364            .into_active_model(),
2365            fruit::ActiveModel {
2366                id: Unchanged(1),
2367                name: Unchanged("Apple".into()),
2368                cake_id: Unchanged(Some(2)),
2369            },
2370        );
2371
2372        assert_eq!(
2373            fruit::Model {
2374                id: 1,
2375                name: "Apple".into(),
2376                cake_id: Some(2),
2377            }
2378            .into_active_model()
2379            .reset_all(),
2380            fruit::ActiveModel {
2381                id: Set(1),
2382                name: Set("Apple".into()),
2383                cake_id: Set(Some(2)),
2384            },
2385        );
2386    }
2387
2388    #[smol_potat::test]
2389    async fn test_reset_2() -> Result<(), DbErr> {
2390        use crate::*;
2391
2392        let db = MockDatabase::new(DbBackend::Postgres)
2393            .append_exec_results(vec![
2394                MockExecResult {
2395                    last_insert_id: 1,
2396                    rows_affected: 1,
2397                },
2398                MockExecResult {
2399                    last_insert_id: 1,
2400                    rows_affected: 1,
2401                },
2402            ])
2403            .append_query_results(vec![
2404                vec![fruit::Model {
2405                    id: 1,
2406                    name: "Apple".to_owned(),
2407                    cake_id: None,
2408                }],
2409                vec![fruit::Model {
2410                    id: 1,
2411                    name: "Apple".to_owned(),
2412                    cake_id: None,
2413                }],
2414            ])
2415            .into_connection();
2416
2417        fruit::Model {
2418            id: 1,
2419            name: "Apple".into(),
2420            cake_id: None,
2421        }
2422        .into_active_model()
2423        .update(&db)
2424        .await?;
2425
2426        fruit::Model {
2427            id: 1,
2428            name: "Apple".into(),
2429            cake_id: None,
2430        }
2431        .into_active_model()
2432        .reset_all()
2433        .update(&db)
2434        .await?;
2435
2436        assert_eq!(
2437            db.into_transaction_log(),
2438            vec![
2439                Transaction::from_sql_and_values(
2440                    DbBackend::Postgres,
2441                    r#"SELECT "fruit"."id", "fruit"."name", "fruit"."cake_id" FROM "fruit" WHERE "fruit"."id" = $1 LIMIT $2"#,
2442                    vec![1i32.into(), 1u64.into()],
2443                ),
2444                Transaction::from_sql_and_values(
2445                    DbBackend::Postgres,
2446                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
2447                    vec!["Apple".into(), Option::<i32>::None.into(), 1i32.into()],
2448                ),
2449            ]
2450        );
2451
2452        Ok(())
2453    }
2454
2455    #[test]
2456    fn test_active_model_default_values() {
2457        assert_eq!(
2458            fruit::ActiveModel::default_values(),
2459            fruit::ActiveModel {
2460                id: Set(0),
2461                name: Set("".into()),
2462                cake_id: Set(None),
2463            },
2464        );
2465
2466        assert_eq!(
2467            lunch_set::ActiveModel::default_values(),
2468            lunch_set::ActiveModel {
2469                id: Set(0),
2470                name: Set("".into()),
2471                tea: NotSet,
2472            },
2473        );
2474    }
2475
2476    #[test]
2477    fn test_active_model_set_parent_key() {
2478        let mut fruit = fruit::Model {
2479            id: 2,
2480            name: "F".into(),
2481            cake_id: None,
2482        }
2483        .into_active_model();
2484
2485        let cake = cake::Model {
2486            id: 4,
2487            name: "C".into(),
2488        }
2489        .into_active_model();
2490
2491        fruit.set_parent_key(&cake).unwrap();
2492
2493        assert_eq!(
2494            fruit,
2495            fruit::ActiveModel {
2496                id: Unchanged(2),
2497                name: Unchanged("F".into()),
2498                cake_id: Set(Some(4)),
2499            }
2500        );
2501
2502        assert!(fruit.clear_parent_key::<cake::Entity>().unwrap());
2503
2504        assert_eq!(
2505            fruit,
2506            fruit::ActiveModel {
2507                id: Unchanged(2),
2508                name: Unchanged("F".into()),
2509                cake_id: Set(None),
2510            }
2511        );
2512
2513        let mut cake_filling = cake_filling::ActiveModel::new();
2514
2515        cake_filling.set_parent_key(&cake).unwrap();
2516
2517        assert_eq!(
2518            cake_filling,
2519            cake_filling::ActiveModel {
2520                cake_id: Set(4),
2521                filling_id: NotSet,
2522            }
2523        );
2524    }
2525}