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.
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    /// Create a Vec of ActiveModels from an Arrow RecordBatch.
524    ///
525    /// Each row in the RecordBatch becomes one ActiveModel.
526    /// Columns are matched by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).
527    /// Columns present in the RecordBatch are marked as `Set`;
528    /// columns absent from the RecordBatch are marked as `NotSet`.
529    ///
530    /// Supported column types: integers (i8–i64, u8–u64), floats (f32, f64),
531    /// `String`/`Text`, `Boolean`, and date/time types (with `with-chrono` or `with-time`).
532    /// Null values in nullable columns are handled.
533    ///
534    /// When both `with-chrono` and `with-time` features are enabled, chrono values
535    /// are attempted first. If the model uses time-crate types, the conversion
536    /// automatically falls back to the time-crate representation.
537    #[cfg(feature = "with-arrow")]
538    fn from_arrow(batch: &sea_orm_arrow::arrow::array::RecordBatch) -> Result<Vec<Self>, DbErr> {
539        use crate::{IdenStatic, Iterable, with_arrow::arrow_array_to_value};
540
541        let num_rows = batch.num_rows();
542        let mut results = Vec::with_capacity(num_rows);
543
544        for row in 0..num_rows {
545            let mut am = Self::default();
546
547            for col in <<Self::Entity as EntityTrait>::Column>::iter() {
548                let col_name = col.as_str();
549
550                if let Some(arrow_col) = batch.column_by_name(col_name) {
551                    let col_def = col.def();
552                    let col_type = col_def.get_column_type();
553                    let value = arrow_array_to_value(arrow_col.as_ref(), col_type, row)?;
554
555                    // When both chrono and time features are enabled, the primary
556                    // conversion produces chrono Values for date/time columns.
557                    // If the model's field uses time-crate types, try_set will fail;
558                    // retry with the time-crate alternative.
559                    #[cfg(all(feature = "with-chrono", feature = "with-time"))]
560                    {
561                        use crate::with_arrow::{arrow_array_to_value_alt, is_datetime_column};
562                        match am.try_set(col, value) {
563                            Ok(()) => {}
564                            Err(first_err) if is_datetime_column(col_type) => {
565                                if let Some(alt_value) =
566                                    arrow_array_to_value_alt(arrow_col.as_ref(), col_type, row)?
567                                {
568                                    am.try_set(col, alt_value)?;
569                                } else {
570                                    return Err(first_err);
571                                }
572                            }
573                            Err(e) => return Err(e),
574                        }
575                    }
576
577                    #[cfg(not(all(feature = "with-chrono", feature = "with-time")))]
578                    am.try_set(col, value)?;
579                } else {
580                    am.not_set(col);
581                }
582            }
583
584            results.push(am);
585        }
586
587        Ok(results)
588    }
589
590    /// Convert a slice of ActiveModels into an Arrow [`RecordBatch`](arrow::array::RecordBatch).
591    ///
592    /// The `schema` determines the output columns: each schema field is matched
593    /// to an entity column by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).
594    /// Columns marked `Set` or `Unchanged` contribute their value;
595    /// `NotSet` columns become null in the output.
596    ///
597    /// Typical usage together with [`ArrowSchema`](crate::ArrowSchema):
598    /// ```ignore
599    /// let schema = MyEntity::arrow_schema();
600    /// let batch = MyActiveModel::to_arrow(&models, &schema)?;
601    /// ```
602    #[cfg(feature = "with-arrow")]
603    fn to_arrow(
604        models: &[Self],
605        schema: &sea_orm_arrow::arrow::datatypes::Schema,
606    ) -> Result<sea_orm_arrow::arrow::array::RecordBatch, DbErr> {
607        use crate::{Iterable, with_arrow::option_values_to_arrow_array};
608        use std::sync::Arc;
609
610        let mut columns: Vec<Arc<dyn sea_orm_arrow::arrow::array::Array>> =
611            Vec::with_capacity(schema.fields().len());
612
613        for field in schema.fields() {
614            let field_name = field.name();
615
616            // Find the entity column whose name matches this schema field
617            let entity_col =
618                <<Self::Entity as EntityTrait>::Column>::iter().find(|c| c.as_str() == field_name);
619
620            if let Some(col) = entity_col {
621                let values: Vec<Option<Value>> = models
622                    .iter()
623                    .map(|m| match m.get(col) {
624                        ActiveValue::Set(v) | ActiveValue::Unchanged(v) => Some(v),
625                        ActiveValue::NotSet => None,
626                    })
627                    .collect();
628
629                let array = option_values_to_arrow_array(&values, field.data_type())?;
630                columns.push(array);
631            } else {
632                // Field in schema but not in entity → null column
633                let array =
634                    sea_orm_arrow::arrow::array::new_null_array(field.data_type(), models.len());
635                columns.push(array);
636            }
637        }
638
639        sea_orm_arrow::arrow::array::RecordBatch::try_new(Arc::new(schema.clone()), columns)
640            .map_err(|e| DbErr::Type(format!("Failed to create RecordBatch: {e}")))
641    }
642
643    /// Return `true` if any attribute of `ActiveModel` is `Set`
644    fn is_changed(&self) -> bool {
645        <Self::Entity as EntityTrait>::Column::iter()
646            .any(|col| matches!(self.get(col), ActiveValue::Set(_)))
647    }
648
649    #[doc(hidden)]
650    /// Set the key to parent's key value for a belongs to relation.
651    fn set_parent_key<R, AM>(&mut self, model: &AM) -> Result<(), DbErr>
652    where
653        R: EntityTrait,
654        AM: ActiveModelTrait<Entity = R>,
655        Self::Entity: Related<R>,
656    {
657        let rel_def = Self::Entity::to();
658
659        if rel_def.is_owner {
660            return Err(DbErr::Type(format!(
661                "Relation from {} to {} is not belongs_to",
662                <Self::Entity as Default>::default().as_str(),
663                <R as Default>::default().as_str()
664            )));
665        }
666
667        let values = get_key_from_active_model(&rel_def.to_col, model)?;
668
669        set_key_on_active_model(&rel_def.from_col, self, values)?;
670
671        Ok(())
672    }
673
674    #[doc(hidden)]
675    fn set_parent_key_for<R, AM>(
676        &mut self,
677        model: &AM,
678        rel: <Self::Entity as EntityTrait>::Relation,
679    ) -> Result<(), DbErr>
680    where
681        R: EntityTrait,
682        AM: ActiveModelTrait<Entity = R>,
683    {
684        let rel_def = rel.def();
685
686        if rel_def.is_owner {
687            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
688        }
689
690        let values = get_key_from_active_model(&rel_def.to_col, model)?;
691
692        set_key_on_active_model(&rel_def.from_col, self, values)?;
693
694        Ok(())
695    }
696
697    #[doc(hidden)]
698    fn set_parent_key_for_def<R, AM>(
699        &mut self,
700        model: &AM,
701        rel_def: &RelationDef,
702    ) -> Result<(), DbErr>
703    where
704        R: EntityTrait,
705        AM: ActiveModelTrait<Entity = R>,
706    {
707        if rel_def.is_owner {
708            return Err(DbErr::Type(format!(
709                "Relation {rel_def:?} is not belongs_to"
710            )));
711        }
712
713        let values = get_key_from_active_model(&rel_def.to_col, model)?;
714
715        set_key_on_active_model(&rel_def.from_col, self, values)?;
716
717        Ok(())
718    }
719
720    #[doc(hidden)]
721    fn set_parent_key_for_self_rev<AM>(
722        &mut self,
723        model: &AM,
724        rel: <Self::Entity as EntityTrait>::Relation,
725    ) -> Result<(), DbErr>
726    where
727        AM: ActiveModelTrait<Entity = Self::Entity>,
728    {
729        let rel_def = rel.def();
730
731        if !rel_def.is_owner {
732            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
733        }
734
735        let values = get_key_from_active_model(&rel_def.from_col, model)?;
736
737        set_key_on_active_model(&rel_def.to_col, self, values)?;
738
739        Ok(())
740    }
741
742    #[doc(hidden)]
743    /// Clear parent association if the relation is optional and return true
744    fn clear_parent_key<R>(&mut self) -> Result<bool, DbErr>
745    where
746        R: EntityTrait,
747        Self::Entity: Related<R>,
748    {
749        let rel_def = Self::Entity::to();
750
751        if rel_def.is_owner {
752            return Err(DbErr::Type(format!(
753                "Relation from {} to {} is not belongs_to",
754                <Self::Entity as Default>::default().as_str(),
755                <R as Default>::default().as_str()
756            )));
757        }
758
759        clear_key_on_active_model(&rel_def.from_col, self)
760    }
761
762    #[doc(hidden)]
763    fn clear_parent_key_for_self_rev(
764        &mut self,
765        rel: <Self::Entity as EntityTrait>::Relation,
766    ) -> Result<bool, DbErr> {
767        let rel_def = rel.def();
768
769        if !rel_def.is_owner {
770            return Err(DbErr::Type(format!("Relation {rel:?} is not owner")));
771        }
772
773        clear_key_on_active_model(&rel_def.to_col, self)
774    }
775
776    #[doc(hidden)]
777    /// Get the key value of belongs to relation
778    fn get_parent_key<R>(&self) -> Result<ValueTuple, DbErr>
779    where
780        R: EntityTrait,
781        Self::Entity: Related<R>,
782    {
783        let rel_def = Self::Entity::to();
784
785        if rel_def.is_owner {
786            return Err(DbErr::Type(format!(
787                "Relation from {} to {} is not belongs_to",
788                <Self::Entity as Default>::default().as_str(),
789                <R as Default>::default().as_str()
790            )));
791        }
792
793        get_key_from_active_model(&rel_def.from_col, self)
794    }
795
796    #[doc(hidden)]
797    /// Get the key value of belongs to relation
798    fn get_parent_key_for(
799        &self,
800        rel: <Self::Entity as EntityTrait>::Relation,
801    ) -> Result<ValueTuple, DbErr> {
802        let rel_def = rel.def();
803
804        if rel_def.is_owner {
805            return Err(DbErr::Type(format!("Relation {rel:?} is not belongs_to")));
806        }
807
808        get_key_from_active_model(&rel_def.from_col, self)
809    }
810
811    #[doc(hidden)]
812    fn find_belongs_to_self(
813        &self,
814        rel: <Self::Entity as EntityTrait>::Relation,
815        db_backend: DbBackend,
816    ) -> Result<crate::query::Select<Self::Entity>, DbErr> {
817        let rel_def = rel.def();
818
819        if !rel_def.is_owner {
820            return Err(DbErr::Type(format!(
821                "Relation {rel:?} is not has_one / has_many"
822            )));
823        }
824
825        let id = get_key_from_active_model(&rel_def.from_col, self)?;
826
827        Ok(Self::Entity::find().filter(
828            column_tuple_in_condition(
829                &<Self::Entity as Default>::default().table_ref(),
830                &rel_def.to_col,
831                &[id],
832                db_backend,
833            )
834            .expect(""),
835        ))
836    }
837
838    #[doc(hidden)]
839    fn find_belongs_to_model<AM>(
840        rel_def: &RelationDef,
841        belongs_to: &AM,
842        db_backend: DbBackend,
843    ) -> Result<crate::query::Select<Self::Entity>, DbErr>
844    where
845        AM: ActiveModelTrait,
846    {
847        if rel_def.is_owner {
848            return Err(DbErr::Type(format!(
849                "Relation {rel_def:?} is not belongs_to"
850            )));
851        }
852
853        let id = get_key_from_active_model(&rel_def.to_col, belongs_to)?;
854        Ok(<Self::Entity as EntityTrait>::find().filter(
855            column_tuple_in_condition(&rel_def.from_tbl, &rel_def.from_col, &[id], db_backend)
856                .expect(""),
857        ))
858    }
859
860    /// Find related Models belonging to self
861    fn find_related<R>(&self, _: R) -> crate::query::Select<R>
862    where
863        R: EntityTrait,
864        Self::Entity: Related<R>,
865    {
866        Self::Entity::find_related().belongs_to_active_model(self)
867    }
868
869    /// Like find_related, but infer type from `AM`
870    #[doc(hidden)]
871    fn find_related_of<AM>(&self, _: &[AM]) -> crate::query::Select<AM::Entity>
872    where
873        AM: ActiveModelTrait,
874        Self::Entity: Related<AM::Entity>,
875    {
876        self.find_related(AM::Entity::default())
877    }
878
879    /// Establish links between self and a related Entity for a many-to-many relation.
880    /// New associations will be added, and leftovers can be optionally deleted.
881    #[doc(hidden)]
882    fn establish_links<J, R, RM, C>(
883        &self,
884        _: J,
885        related_models: &[RM],
886        delete_leftover: bool,
887        db: &C,
888    ) -> Result<(), DbErr>
889    where
890        R: EntityTrait,
891        RM: ActiveModelTrait<Entity = R>,
892        J: EntityTrait + Related<R> + Related<Self::Entity>,
893        J::Model: IntoActiveModel<J::ActiveModel>,
894        J::ActiveModel: ActiveModelBehavior,
895        C: ConnectionTrait,
896    {
897        let left = <J as Related<Self::Entity>>::to();
898        let right = <J as Related<R>>::to();
899
900        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
901    }
902
903    /// Establish links for self-referencing many-to-many relation
904    #[doc(hidden)]
905    fn establish_links_self<J, RM, C>(
906        &self,
907        _: J,
908        related_models: &[RM],
909        delete_leftover: bool,
910        db: &C,
911    ) -> Result<(), DbErr>
912    where
913        RM: ActiveModelTrait<Entity = Self::Entity>,
914        J: EntityTrait,
915        J::Model: IntoActiveModel<J::ActiveModel>,
916        J::ActiveModel: ActiveModelBehavior,
917        C: ConnectionTrait,
918        Self::Entity: RelatedSelfVia<J>,
919    {
920        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
921        let right = <Self::Entity as RelatedSelfVia<J>>::to();
922
923        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
924    }
925
926    /// Establish links for self-referencing many-to-many relation, but left-right reversed
927    #[doc(hidden)]
928    fn establish_links_self_rev<J, RM, C>(
929        &self,
930        _: J,
931        related_models: &[RM],
932        delete_leftover: bool,
933        db: &C,
934    ) -> Result<(), DbErr>
935    where
936        RM: ActiveModelTrait<Entity = Self::Entity>,
937        J: EntityTrait,
938        J::Model: IntoActiveModel<J::ActiveModel>,
939        J::ActiveModel: ActiveModelBehavior,
940        C: ConnectionTrait,
941        Self::Entity: RelatedSelfVia<J>,
942    {
943        let left = <Self::Entity as RelatedSelfVia<J>>::to();
944        let right = <Self::Entity as RelatedSelfVia<J>>::via().rev();
945
946        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)
947    }
948
949    /// Inverse of establish link, break links between two many-to-many models
950    #[doc(hidden)]
951    fn delete_links<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
952    where
953        J: EntityTrait + Related<Self::Entity>,
954        C: ConnectionTrait,
955    {
956        let rel_def = <J as Related<Self::Entity>>::to();
957        let id = get_key_from_active_model(&rel_def.to_col, self)?;
958
959        J::delete_many()
960            .filter(
961                column_tuple_in_condition(
962                    &rel_def.from_tbl,
963                    &rel_def.from_col,
964                    &[id],
965                    db.get_database_backend(),
966                )
967                .expect(""),
968            )
969            .exec(db)
970    }
971
972    /// Like `delete_links` but for self-referencing relations
973    #[doc(hidden)]
974    fn delete_links_self<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>
975    where
976        J: EntityTrait,
977        C: ConnectionTrait,
978        Self::Entity: RelatedSelfVia<J>,
979    {
980        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();
981        let right = <Self::Entity as RelatedSelfVia<J>>::to();
982
983        let id = get_key_from_active_model(&left.to_col, self)?;
984
985        if left.to_col != right.to_col {
986            return Err(DbErr::Type("Expect Self Referencing Relation".into()));
987        }
988
989        J::delete_many()
990            .filter(
991                Condition::any()
992                    .add(
993                        column_tuple_in_condition(
994                            &left.from_tbl,
995                            &left.from_col,
996                            std::slice::from_ref(&id),
997                            db.get_database_backend(),
998                        )
999                        .expect(""),
1000                    )
1001                    .add(
1002                        column_tuple_in_condition(
1003                            &right.from_tbl,
1004                            &right.from_col,
1005                            std::slice::from_ref(&id),
1006                            db.get_database_backend(),
1007                        )
1008                        .expect(""),
1009                    ),
1010            )
1011            .exec(db)
1012    }
1013}
1014
1015/// A Trait for overriding the ActiveModel behavior
1016///
1017/// ### Example
1018/// ```ignore
1019/// use sea_orm::entity::prelude::*;
1020///
1021///  // Use [DeriveEntity] to derive the EntityTrait automatically
1022/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
1023/// pub struct Entity;
1024///
1025/// /// The [EntityName] describes the name of a table
1026/// impl EntityName for Entity {
1027///     fn table_name(&self) -> &'static str {
1028///         "cake"
1029///     }
1030/// }
1031///
1032/// // Derive the ActiveModel
1033/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
1034/// pub struct Model {
1035///     pub id: i32,
1036///     pub name: String,
1037/// }
1038///
1039/// impl ActiveModelBehavior for ActiveModel {}
1040/// ```
1041/// See module level docs [crate::entity] for a full example
1042#[allow(unused_variables)]
1043pub trait ActiveModelBehavior: ActiveModelTrait {
1044    /// Create a new ActiveModel with default values. This is also called by `Default::default()`.
1045    ///
1046    /// You can override it like the following:
1047    ///
1048    /// ```ignore
1049    /// fn new() -> Self {
1050    ///     Self {
1051    ///         status: Set(Status::New),
1052    ///         ..ActiveModelTrait::default()
1053    ///     }
1054    /// }
1055    /// ```
1056    fn new() -> Self {
1057        <Self as ActiveModelTrait>::default()
1058    }
1059
1060    /// Will be called before `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
1061    fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>
1062    where
1063        C: ConnectionTrait,
1064    {
1065        Ok(self)
1066    }
1067
1068    /// Will be called after `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`
1069    fn after_save<C>(
1070        model: <Self::Entity as EntityTrait>::Model,
1071        db: &C,
1072        insert: bool,
1073    ) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>
1074    where
1075        C: ConnectionTrait,
1076    {
1077        Ok(model)
1078    }
1079
1080    /// Will be called before `ActiveModel::delete`
1081    fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>
1082    where
1083        C: ConnectionTrait,
1084    {
1085        Ok(self)
1086    }
1087
1088    /// Will be called after `ActiveModel::delete`
1089    fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>
1090    where
1091        C: ConnectionTrait,
1092    {
1093        Ok(self)
1094    }
1095}
1096
1097/// A Trait for any type that can be converted into an `ActiveModel`,
1098/// can be derived using `DeriveIntoActiveModel`.
1099///
1100/// ## Derive Macro Example
1101///
1102/// ```rust
1103/// use sea_orm::DeriveIntoActiveModel;
1104/// mod fruit {
1105///     use sea_orm::entity::prelude::*;
1106///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1107///     #[sea_orm(table_name = "fruit")]
1108///     pub struct Model {
1109///         #[sea_orm(primary_key)]
1110///         pub id: i32,
1111///         pub name: String,
1112///         pub cake_id: Option<i32>,
1113///     }
1114///     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1115///     pub enum Relation {}
1116///     impl ActiveModelBehavior for ActiveModel {}
1117/// }
1118///
1119/// #[derive(DeriveIntoActiveModel)]
1120/// #[sea_orm(active_model = "fruit::ActiveModel")]
1121/// struct NewFruit {
1122///     name: String,
1123///     // `id` and `cake_id` are omitted - they become `NotSet`
1124/// }
1125/// ```
1126///
1127/// ## `set(...)` - always set absent ActiveModel fields
1128///
1129/// ```rust
1130/// # mod fruit {
1131/// #     use sea_orm::entity::prelude::*;
1132/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1133/// #     #[sea_orm(table_name = "fruit")]
1134/// #     pub struct Model {
1135/// #         #[sea_orm(primary_key)]
1136/// #         pub id: i32,
1137/// #         pub name: String,
1138/// #         pub cake_id: Option<i32>,
1139/// #     }
1140/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1141/// #     pub enum Relation {}
1142/// #     impl ActiveModelBehavior for ActiveModel {}
1143/// # }
1144/// use sea_orm::DeriveIntoActiveModel;
1145///
1146/// #[derive(DeriveIntoActiveModel)]
1147/// #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "None"))]
1148/// struct NewFruit {
1149///     name: String,
1150///     // `cake_id` is not on the struct, but will always be `Set(None)`
1151/// }
1152/// ```
1153///
1154/// ## `default = "expr"` - fallback for `Option<T>` struct fields
1155///
1156/// ```rust
1157/// # mod fruit {
1158/// #     use sea_orm::entity::prelude::*;
1159/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1160/// #     #[sea_orm(table_name = "fruit")]
1161/// #     pub struct Model {
1162/// #         #[sea_orm(primary_key)]
1163/// #         pub id: i32,
1164/// #         pub name: String,
1165/// #         pub cake_id: Option<i32>,
1166/// #     }
1167/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1168/// #     pub enum Relation {}
1169/// #     impl ActiveModelBehavior for ActiveModel {}
1170/// # }
1171/// use sea_orm::DeriveIntoActiveModel;
1172///
1173/// #[derive(DeriveIntoActiveModel)]
1174/// #[sea_orm(active_model = "fruit::ActiveModel")]
1175/// struct UpdateFruit {
1176///     /// `Some("Apple")` -> `Set("Apple")`, `None` ->`Set("Unnamed")`
1177///     #[sea_orm(default = "String::from(\"Unnamed\")")]
1178///     name: Option<String>,
1179/// }
1180/// ```
1181pub trait IntoActiveModel<A>
1182where
1183    A: ActiveModelTrait,
1184{
1185    /// Method to call to perform the conversion
1186    fn into_active_model(self) -> A;
1187}
1188
1189impl<A> IntoActiveModel<A> for A
1190where
1191    A: ActiveModelTrait,
1192{
1193    fn into_active_model(self) -> A {
1194        self
1195    }
1196}
1197
1198fn establish_links<EM, J, RM, C>(
1199    model: &EM,
1200    related_models: &[RM],
1201    left: RelationDef,
1202    right: RelationDef,
1203    delete_leftover: bool,
1204    db: &C,
1205) -> Result<(), DbErr>
1206where
1207    EM: ActiveModelTrait,
1208    RM: ActiveModelTrait,
1209    J: EntityTrait,
1210    J::Model: IntoActiveModel<J::ActiveModel>,
1211    J::ActiveModel: ActiveModelBehavior,
1212    C: ConnectionTrait,
1213{
1214    let mut require_leftover = true;
1215
1216    if related_models.is_empty() {
1217        // if there are no related models, then there is no risk of insert conflict
1218        require_leftover = false;
1219    }
1220
1221    let primary_key = J::primary_key_identity();
1222    if require_leftover
1223        && primary_key.fully_contains(&left.from_col)
1224        && primary_key.fully_contains(&right.from_col)
1225    {
1226        // if the primary key is a composite key of the two relations
1227        // we can use on conflict no action safely
1228        require_leftover = false;
1229    }
1230
1231    let mut leftover = Vec::new();
1232    if delete_leftover || require_leftover {
1233        for item in <J::ActiveModel as ActiveModelTrait>::find_belongs_to_model(
1234            &left,
1235            model,
1236            db.get_database_backend(),
1237        )?
1238        .all(db)?
1239        {
1240            let item = item.into_active_model();
1241            let key = get_key_from_active_model(&right.from_col, &item)?;
1242            leftover.push((item, key));
1243        }
1244    }
1245    let leftover = leftover; // un-mut
1246
1247    let mut via_models = Vec::new();
1248    let mut all_keys = std::collections::HashSet::new();
1249
1250    for related_model in related_models {
1251        let mut via: J::ActiveModel = ActiveModelBehavior::new();
1252        via.set_parent_key_for_def(model, &left)?;
1253        via.set_parent_key_for_def(related_model, &right)?;
1254        let via_key = get_key_from_active_model(&right.from_col, &via)?;
1255        if !leftover.iter().any(|t| t.1 == via_key) {
1256            // if not already exist, save for insert
1257            via_models.push(via);
1258        }
1259        if delete_leftover {
1260            all_keys.insert(via_key);
1261        }
1262    }
1263
1264    if delete_leftover {
1265        let mut to_delete = Vec::new();
1266        for (leftover, key) in leftover {
1267            if !all_keys.contains(&key) {
1268                to_delete.push(
1269                    leftover
1270                        .get_primary_key_value()
1271                        .expect("item is a full model"),
1272                );
1273            }
1274        }
1275        if !to_delete.is_empty() {
1276            J::delete_many()
1277                .filter_by_value_tuples(&to_delete, db.get_database_backend())
1278                .exec(db)?;
1279        }
1280    }
1281
1282    if !via_models.is_empty() {
1283        // insert new junctions
1284        J::insert_many(via_models)
1285            .on_conflict_do_nothing()
1286            .exec(db)?;
1287    }
1288
1289    Ok(())
1290}
1291
1292#[cfg(test)]
1293mod tests {
1294    use crate::{DbErr, entity::*, tests_cfg::*};
1295    use pretty_assertions::assert_eq;
1296
1297    #[cfg(feature = "with-json")]
1298    use serde_json::json;
1299
1300    #[test]
1301    #[cfg(feature = "macros")]
1302    fn test_derive_into_active_model_1() {
1303        mod my_fruit {
1304            pub use super::fruit::*;
1305            use crate as sea_orm;
1306            use crate::entity::prelude::*;
1307
1308            #[derive(DeriveIntoActiveModel)]
1309            pub struct NewFruit {
1310                // id is omitted
1311                pub name: String,
1312                // it is required as opposed to optional in Model
1313                pub cake_id: i32,
1314            }
1315        }
1316
1317        assert_eq!(
1318            my_fruit::NewFruit {
1319                name: "Apple".to_owned(),
1320                cake_id: 1,
1321            }
1322            .into_active_model(),
1323            fruit::ActiveModel {
1324                id: NotSet,
1325                name: Set("Apple".to_owned()),
1326                cake_id: Set(Some(1)),
1327            }
1328        );
1329    }
1330
1331    #[test]
1332    #[cfg(feature = "macros")]
1333    fn test_derive_into_active_model_2() {
1334        use crate as sea_orm;
1335        use crate::entity::prelude::*;
1336
1337        #[derive(DeriveIntoActiveModel)]
1338        #[sea_orm(active_model = "fruit::ActiveModel")]
1339        struct RequiredFruitName {
1340            name: String,
1341        }
1342
1343        assert_eq!(
1344            RequiredFruitName {
1345                name: "Apple Pie".to_owned(),
1346            }
1347            .into_active_model(),
1348            fruit::ActiveModel {
1349                id: NotSet,
1350                name: Set("Apple Pie".to_owned()),
1351                cake_id: NotSet,
1352            }
1353        );
1354
1355        #[derive(DeriveIntoActiveModel)]
1356        #[sea_orm(active_model = "fruit::ActiveModel")]
1357        struct OptionalFruitName {
1358            name: Option<String>,
1359        }
1360
1361        assert_eq!(
1362            OptionalFruitName {
1363                name: Some("Apple Pie".to_owned()),
1364            }
1365            .into_active_model(),
1366            fruit::ActiveModel {
1367                id: NotSet,
1368                name: Set("Apple Pie".to_owned()),
1369                cake_id: NotSet,
1370            }
1371        );
1372
1373        assert_eq!(
1374            OptionalFruitName { name: None }.into_active_model(),
1375            fruit::ActiveModel {
1376                id: NotSet,
1377                name: NotSet,
1378                cake_id: NotSet,
1379            }
1380        );
1381
1382        #[derive(DeriveIntoActiveModel)]
1383        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1384        struct RequiredAndNotNullFruitCake {
1385            cake_id: i32,
1386        }
1387
1388        assert_eq!(
1389            RequiredAndNotNullFruitCake { cake_id: 1 }.into_active_model(),
1390            fruit::ActiveModel {
1391                id: NotSet,
1392                name: NotSet,
1393                cake_id: Set(Some(1)),
1394            }
1395        );
1396
1397        #[derive(DeriveIntoActiveModel)]
1398        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1399        struct OptionalAndNotNullFruitCake {
1400            cake_id: Option<i32>,
1401        }
1402
1403        assert_eq!(
1404            OptionalAndNotNullFruitCake { cake_id: Some(1) }.into_active_model(),
1405            fruit::ActiveModel {
1406                id: NotSet,
1407                name: NotSet,
1408                cake_id: Set(Some(1)),
1409            }
1410        );
1411
1412        assert_eq!(
1413            OptionalAndNotNullFruitCake { cake_id: None }.into_active_model(),
1414            fruit::ActiveModel {
1415                id: NotSet,
1416                name: NotSet,
1417                cake_id: NotSet,
1418            }
1419        );
1420
1421        #[derive(DeriveIntoActiveModel)]
1422        #[sea_orm(active_model = "<fruit::Entity as EntityTrait>::ActiveModel")]
1423        struct OptionalAndNullableFruitCake {
1424            cake_id: Option<Option<i32>>,
1425        }
1426
1427        assert_eq!(
1428            OptionalAndNullableFruitCake {
1429                cake_id: Some(Some(1)),
1430            }
1431            .into_active_model(),
1432            fruit::ActiveModel {
1433                id: NotSet,
1434                name: NotSet,
1435                cake_id: Set(Some(1)),
1436            }
1437        );
1438
1439        assert_eq!(
1440            OptionalAndNullableFruitCake {
1441                cake_id: Some(None),
1442            }
1443            .into_active_model(),
1444            fruit::ActiveModel {
1445                id: NotSet,
1446                name: NotSet,
1447                cake_id: Set(None),
1448            }
1449        );
1450
1451        assert_eq!(
1452            OptionalAndNullableFruitCake { cake_id: None }.into_active_model(),
1453            fruit::ActiveModel {
1454                id: NotSet,
1455                name: NotSet,
1456                cake_id: NotSet,
1457            }
1458        );
1459    }
1460
1461    #[test]
1462    #[cfg(feature = "macros")]
1463    fn test_derive_into_active_model_fill_single() {
1464        use crate as sea_orm;
1465        use crate::entity::prelude::*;
1466
1467        #[derive(DeriveIntoActiveModel)]
1468        #[sea_orm(active_model = "fruit::ActiveModel", fill(cake_id = "None"))]
1469        struct NewFruit {
1470            name: String,
1471        }
1472
1473        assert_eq!(
1474            NewFruit {
1475                name: "Apple".to_owned(),
1476            }
1477            .into_active_model(),
1478            fruit::ActiveModel {
1479                id: NotSet,
1480                name: Set("Apple".to_owned()),
1481                cake_id: Set(None),
1482            }
1483        );
1484    }
1485
1486    #[test]
1487    #[cfg(feature = "macros")]
1488    fn test_derive_into_active_model_set_multiple() {
1489        use crate as sea_orm;
1490        use crate::entity::prelude::*;
1491
1492        #[derive(DeriveIntoActiveModel)]
1493        #[sea_orm(
1494            active_model = "fruit::ActiveModel",
1495            set(name = "String::from(\"cherry\")", cake_id = "None")
1496        )]
1497        struct IdOnlyFruit {
1498            id: i32,
1499        }
1500        assert_eq!(
1501            IdOnlyFruit { id: 1 }.into_active_model(),
1502            fruit::ActiveModel {
1503                id: Set(1),
1504                name: Set("cherry".to_owned()),
1505                cake_id: Set(None),
1506            }
1507        );
1508
1509        #[derive(DeriveIntoActiveModel)]
1510        #[sea_orm(
1511            active_model = "fruit::ActiveModel",
1512            set(name = "String::from(\"cherry\")"),
1513            set(cake_id = "None")
1514        )]
1515        struct IdOnlyFruit2 {
1516            id: i32,
1517        }
1518        assert_eq!(
1519            IdOnlyFruit2 { id: 1 }.into_active_model(),
1520            fruit::ActiveModel {
1521                id: Set(1),
1522                name: Set("cherry".to_owned()),
1523                cake_id: Set(None),
1524            }
1525        );
1526    }
1527
1528    #[test]
1529    #[cfg(feature = "macros")]
1530    fn test_derive_into_active_model_set_separate_attrs() {
1531        use crate as sea_orm;
1532        use crate::entity::prelude::*;
1533
1534        #[derive(DeriveIntoActiveModel)]
1535        #[sea_orm(
1536            active_model = "fruit::ActiveModel",
1537            set(name = "String::from(\"cherry\")")
1538        )]
1539        #[sea_orm(set(cake_id = "None"))]
1540        struct IdOnlyFruit {
1541            id: i32,
1542        }
1543
1544        assert_eq!(
1545            IdOnlyFruit { id: 1 }.into_active_model(),
1546            fruit::ActiveModel {
1547                id: Set(1),
1548                name: Set("cherry".to_owned()),
1549                cake_id: Set(None),
1550            }
1551        );
1552    }
1553
1554    #[test]
1555    #[cfg(feature = "macros")]
1556    fn test_derive_into_active_model_ignore() {
1557        use crate as sea_orm;
1558        use crate::entity::prelude::*;
1559
1560        #[derive(DeriveIntoActiveModel)]
1561        #[sea_orm(active_model = "fruit::ActiveModel")]
1562        struct NewFruit {
1563            name: String,
1564            cake_id: i32,
1565            #[sea_orm(ignore)]
1566            _extra: String,
1567        }
1568
1569        assert_eq!(
1570            NewFruit {
1571                name: "Apple".to_owned(),
1572                cake_id: 1,
1573                _extra: "ignored".to_owned(),
1574            }
1575            .into_active_model(),
1576            fruit::ActiveModel {
1577                id: NotSet,
1578                name: Set("Apple".to_owned()),
1579                cake_id: Set(Some(1)),
1580            }
1581        );
1582    }
1583
1584    #[test]
1585    #[cfg(feature = "macros")]
1586    fn test_derive_into_active_model_skip() {
1587        use crate as sea_orm;
1588        use crate::entity::prelude::*;
1589
1590        #[derive(DeriveIntoActiveModel)]
1591        #[sea_orm(active_model = "fruit::ActiveModel")]
1592        struct NewFruit {
1593            name: String,
1594            #[sea_orm(skip)]
1595            _extra: String,
1596        }
1597
1598        assert_eq!(
1599            NewFruit {
1600                name: "Apple".to_owned(),
1601                _extra: "skipped".to_owned(),
1602            }
1603            .into_active_model(),
1604            fruit::ActiveModel {
1605                id: NotSet,
1606                name: Set("Apple".to_owned()),
1607                cake_id: NotSet,
1608            }
1609        );
1610    }
1611
1612    #[test]
1613    #[cfg(feature = "macros")]
1614    fn test_derive_into_active_model_set_and_ignore() {
1615        use crate as sea_orm;
1616        use crate::entity::prelude::*;
1617
1618        #[derive(DeriveIntoActiveModel)]
1619        #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "Some(42)"))]
1620        struct NewFruit {
1621            name: String,
1622            #[sea_orm(ignore)]
1623            _extra: String,
1624        }
1625
1626        assert_eq!(
1627            NewFruit {
1628                name: "Apple".to_owned(),
1629                _extra: "ignored".to_owned(),
1630            }
1631            .into_active_model(),
1632            fruit::ActiveModel {
1633                id: NotSet,
1634                name: Set("Apple".to_owned()),
1635                cake_id: Set(Some(42)),
1636            }
1637        );
1638    }
1639
1640    #[test]
1641    #[cfg(feature = "macros")]
1642    fn test_derive_into_active_model_foreign_ignore() {
1643        use serde::{Deserialize, Serialize};
1644
1645        use crate as sea_orm;
1646        use crate::entity::prelude::*;
1647
1648        #[derive(DeriveIntoActiveModel, Serialize, Deserialize)]
1649        #[sea_orm(active_model = "fruit::ActiveModel")]
1650        struct NewFruit {
1651            #[sea_orm(ignore)]
1652            id: i32,
1653            name: String,
1654            #[serde(skip)]
1655            cake_id: Option<i32>,
1656        }
1657
1658        assert_eq!(
1659            NewFruit {
1660                id: 1.to_owned(),
1661                name: "Apple".to_owned(),
1662                cake_id: Some(42)
1663            }
1664            .into_active_model(),
1665            fruit::ActiveModel {
1666                id: NotSet,
1667                name: Set("Apple".to_owned()),
1668                cake_id: Set(Some(42)),
1669            }
1670        );
1671    }
1672
1673    #[test]
1674    #[cfg(feature = "macros")]
1675    fn test_derive_into_active_model_exhaustive() {
1676        use crate as sea_orm;
1677        use crate::entity::prelude::*;
1678
1679        #[derive(DeriveIntoActiveModel)]
1680        #[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
1681        struct FullFruit {
1682            id: i32,
1683            name: String,
1684        }
1685
1686        assert_eq!(
1687            FullFruit {
1688                id: 1,
1689                name: "Apple".to_owned(),
1690            }
1691            .into_active_model(),
1692            fruit::ActiveModel {
1693                id: Set(1),
1694                name: Set("Apple".to_owned()),
1695                cake_id: Set(None),
1696            }
1697        );
1698    }
1699
1700    #[test]
1701    #[cfg(feature = "macros")]
1702    fn test_derive_into_active_model_multiple_sets() {
1703        use crate as sea_orm;
1704        use crate::entity::prelude::*;
1705
1706        const DEFULT_CAKE_ID: i32 = 1;
1707        #[derive(DeriveIntoActiveModel)]
1708        #[sea_orm(
1709            active_model = "fruit::ActiveModel",
1710            exhaustive,
1711            set(cake_id = "Some(DEFULT_CAKE_ID)")
1712        )]
1713        struct FullFruit {
1714            id: i32,
1715            name: String,
1716        }
1717
1718        assert_eq!(
1719            FullFruit {
1720                id: 1,
1721                name: "Apple".to_owned(),
1722            }
1723            .into_active_model(),
1724            fruit::ActiveModel {
1725                id: Set(1),
1726                name: Set("Apple".to_owned()),
1727                cake_id: Set(Some(1)),
1728            }
1729        );
1730    }
1731
1732    #[test]
1733    #[cfg(feature = "macros")]
1734    fn test_derive_into_active_model_field_empty_default() {
1735        use crate as sea_orm;
1736        use crate::entity::prelude::*;
1737
1738        #[derive(DeriveIntoActiveModel)]
1739        #[sea_orm(active_model = "fruit::ActiveModel")]
1740        struct NewFruit {
1741            #[sea_orm(default)]
1742            name: Option<String>,
1743        }
1744
1745        // Some(v) -> Set(v)
1746        assert_eq!(
1747            NewFruit {
1748                name: Some("Apple".to_owned()),
1749            }
1750            .into_active_model(),
1751            fruit::ActiveModel {
1752                id: NotSet,
1753                name: Set("Apple".to_owned()),
1754                cake_id: NotSet,
1755            }
1756        );
1757
1758        // None -> Set(fallback)
1759        assert_eq!(
1760            NewFruit { name: None }.into_active_model(),
1761            fruit::ActiveModel {
1762                id: NotSet,
1763                name: Set("".to_owned()),
1764                cake_id: NotSet,
1765            }
1766        );
1767    }
1768
1769    #[test]
1770    #[cfg(feature = "macros")]
1771    fn test_derive_into_active_model_field_custom_option() {
1772        use crate as sea_orm;
1773        use crate::entity::prelude::*;
1774        mod foreign_crate {
1775            #[derive(Debug, Clone, PartialEq, Eq)]
1776            pub enum CustomOption<T> {
1777                None,
1778                Some(T),
1779            }
1780
1781            impl From<CustomOption<String>> for Option<String> {
1782                fn from(option: CustomOption<String>) -> Self {
1783                    match option {
1784                        CustomOption::None => Option::None,
1785                        CustomOption::Some(value) => value.into(),
1786                    }
1787                }
1788            }
1789        }
1790        use foreign_crate::CustomOption;
1791
1792        #[derive(DeriveIntoActiveModel)]
1793        #[sea_orm(active_model = "fruit::ActiveModel")]
1794        struct NewFruit {
1795            #[sea_orm(default)]
1796            name: CustomOption<String>,
1797        }
1798
1799        // Some(v) -> Set(v)
1800        assert_eq!(
1801            NewFruit {
1802                name: CustomOption::Some("Apple".to_owned()),
1803            }
1804            .into_active_model(),
1805            fruit::ActiveModel {
1806                id: NotSet,
1807                name: Set("Apple".to_owned()),
1808                cake_id: NotSet,
1809            }
1810        );
1811
1812        // None -> Set(fallback)
1813        assert_eq!(
1814            NewFruit {
1815                name: CustomOption::None
1816            }
1817            .into_active_model(),
1818            fruit::ActiveModel {
1819                id: NotSet,
1820                name: Set("".to_owned()),
1821                cake_id: NotSet,
1822            }
1823        );
1824    }
1825
1826    #[test]
1827    #[cfg(feature = "macros")]
1828    fn test_derive_into_active_model_field_default_some() {
1829        use crate as sea_orm;
1830        use crate::entity::prelude::*;
1831
1832        #[derive(DeriveIntoActiveModel)]
1833        #[sea_orm(active_model = "fruit::ActiveModel")]
1834        struct NewFruit {
1835            #[sea_orm(default = "String::from(\"Unnamed\")")]
1836            name: Option<String>,
1837        }
1838
1839        // Some(v) -> Set(v)
1840        assert_eq!(
1841            NewFruit {
1842                name: Some("Apple".to_owned()),
1843            }
1844            .into_active_model(),
1845            fruit::ActiveModel {
1846                id: NotSet,
1847                name: Set("Apple".to_owned()),
1848                cake_id: NotSet,
1849            }
1850        );
1851
1852        // None -> Set(fallback)
1853        assert_eq!(
1854            NewFruit { name: None }.into_active_model(),
1855            fruit::ActiveModel {
1856                id: NotSet,
1857                name: Set("Unnamed".to_owned()),
1858                cake_id: NotSet,
1859            }
1860        );
1861    }
1862
1863    #[test]
1864    #[cfg(feature = "macros")]
1865    fn test_derive_into_active_model_field_default_with_set() {
1866        use crate as sea_orm;
1867        use crate::entity::prelude::*;
1868
1869        #[derive(DeriveIntoActiveModel)]
1870        #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "Some(99)"))]
1871        struct NewFruit {
1872            #[sea_orm(default = "String::from(\"Unnamed\")")]
1873            name: Option<String>,
1874            #[sea_orm(ignore)]
1875            _extra: String,
1876        }
1877
1878        assert_eq!(
1879            NewFruit {
1880                name: Some("Apple".to_owned()),
1881                _extra: "ignored".to_owned(),
1882            }
1883            .into_active_model(),
1884            fruit::ActiveModel {
1885                id: NotSet,
1886                name: Set("Apple".to_owned()),
1887                cake_id: Set(Some(99)),
1888            }
1889        );
1890
1891        assert_eq!(
1892            NewFruit {
1893                name: None,
1894                _extra: "ignored".to_owned(),
1895            }
1896            .into_active_model(),
1897            fruit::ActiveModel {
1898                id: NotSet,
1899                name: Set("Unnamed".to_owned()),
1900                cake_id: Set(Some(99)),
1901            }
1902        );
1903    }
1904
1905    #[test]
1906    #[cfg(feature = "macros")]
1907    fn test_derive_into_active_model_field_default_exhaustive() {
1908        use crate as sea_orm;
1909        use crate::entity::prelude::*;
1910
1911        #[derive(DeriveIntoActiveModel)]
1912        #[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
1913        struct NewFruit {
1914            id: i32,
1915            #[sea_orm(default = "String::from(\"Unnamed\")")]
1916            name: Option<String>,
1917        }
1918
1919        assert_eq!(
1920            NewFruit {
1921                id: 1,
1922                name: Some("Apple".to_owned()),
1923            }
1924            .into_active_model(),
1925            fruit::ActiveModel {
1926                id: Set(1),
1927                name: Set("Apple".to_owned()),
1928                cake_id: Set(None),
1929            }
1930        );
1931
1932        assert_eq!(
1933            NewFruit { id: 2, name: None }.into_active_model(),
1934            fruit::ActiveModel {
1935                id: Set(2),
1936                name: Set("Unnamed".to_owned()),
1937                cake_id: Set(None),
1938            }
1939        );
1940    }
1941
1942    #[test]
1943    #[cfg(feature = "macros")]
1944    fn test_derive_try_into_model_1() {
1945        mod my_fruit {
1946            use crate as sea_orm;
1947            use crate::entity::prelude::*;
1948
1949            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1950            #[sea_orm(table_name = "fruit")]
1951            pub struct Model {
1952                #[sea_orm(primary_key)]
1953                pub id: i32,
1954                pub name: String,
1955                pub cake_id: Option<i32>,
1956            }
1957
1958            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
1959            pub enum Relation {}
1960
1961            impl ActiveModelBehavior for ActiveModel {}
1962        }
1963        assert_eq!(
1964            my_fruit::ActiveModel {
1965                id: Set(1),
1966                name: Set("Pineapple".to_owned()),
1967                cake_id: Set(None),
1968            }
1969            .try_into_model()
1970            .unwrap(),
1971            my_fruit::Model {
1972                id: 1,
1973                name: "Pineapple".to_owned(),
1974                cake_id: None,
1975            }
1976        );
1977
1978        assert_eq!(
1979            my_fruit::ActiveModel {
1980                id: Set(2),
1981                name: Set("Apple".to_owned()),
1982                cake_id: Set(Some(1)),
1983            }
1984            .try_into_model()
1985            .unwrap(),
1986            my_fruit::Model {
1987                id: 2,
1988                name: "Apple".to_owned(),
1989                cake_id: Some(1),
1990            }
1991        );
1992
1993        assert_eq!(
1994            my_fruit::ActiveModel {
1995                id: Set(1),
1996                name: NotSet,
1997                cake_id: Set(None),
1998            }
1999            .try_into_model(),
2000            Err(DbErr::AttrNotSet(String::from("name")))
2001        );
2002
2003        assert_eq!(
2004            my_fruit::ActiveModel {
2005                id: Set(1),
2006                name: Set("Pineapple".to_owned()),
2007                cake_id: NotSet,
2008            }
2009            .try_into_model(),
2010            Err(DbErr::AttrNotSet(String::from("cake_id")))
2011        );
2012    }
2013
2014    #[test]
2015    #[cfg(feature = "macros")]
2016    fn test_derive_try_into_model_2() {
2017        mod my_fruit {
2018            use crate as sea_orm;
2019            use crate::entity::prelude::*;
2020
2021            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
2022            #[sea_orm(table_name = "fruit")]
2023            pub struct Model {
2024                #[sea_orm(primary_key)]
2025                pub id: i32,
2026                pub name: String,
2027                #[sea_orm(ignore)]
2028                pub cake_id: Option<i32>,
2029            }
2030
2031            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
2032            pub enum Relation {}
2033
2034            impl ActiveModelBehavior for ActiveModel {}
2035        }
2036        assert_eq!(
2037            my_fruit::ActiveModel {
2038                id: Set(1),
2039                name: Set("Pineapple".to_owned()),
2040            }
2041            .try_into_model()
2042            .unwrap(),
2043            my_fruit::Model {
2044                id: 1,
2045                name: "Pineapple".to_owned(),
2046                cake_id: None,
2047            }
2048        );
2049    }
2050
2051    #[test]
2052    #[cfg(feature = "macros")]
2053    fn test_derive_try_into_model_3() {
2054        mod my_fruit {
2055            use crate as sea_orm;
2056            use crate::entity::prelude::*;
2057
2058            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
2059            #[sea_orm(table_name = "fruit")]
2060            pub struct Model {
2061                #[sea_orm(primary_key)]
2062                pub id: i32,
2063                #[sea_orm(ignore)]
2064                pub name: String,
2065                pub cake_id: Option<i32>,
2066            }
2067
2068            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
2069            pub enum Relation {}
2070
2071            impl ActiveModelBehavior for ActiveModel {}
2072        }
2073        assert_eq!(
2074            my_fruit::ActiveModel {
2075                id: Set(1),
2076                cake_id: Set(Some(1)),
2077            }
2078            .try_into_model()
2079            .unwrap(),
2080            my_fruit::Model {
2081                id: 1,
2082                name: "".to_owned(),
2083                cake_id: Some(1),
2084            }
2085        );
2086    }
2087
2088    #[test]
2089    #[cfg(feature = "with-json")]
2090    fn test_active_model_set_from_json_1() {
2091        assert_eq!(
2092            cake::ActiveModel::from_json(json!({
2093                "id": 1,
2094                "name": "Apple Pie",
2095            }))
2096            .unwrap(),
2097            cake::ActiveModel {
2098                id: Set(1),
2099                name: Set("Apple Pie".to_owned()),
2100            }
2101        );
2102
2103        assert_eq!(
2104            cake::ActiveModel::from_json(json!({
2105                "id": 1,
2106            }))
2107            .unwrap(),
2108            cake::ActiveModel {
2109                id: Set(1),
2110                name: NotSet,
2111            }
2112        );
2113
2114        assert_eq!(
2115            cake::ActiveModel::from_json(json!({
2116                "name": "Apple Pie",
2117            }))
2118            .unwrap(),
2119            cake::ActiveModel {
2120                id: NotSet,
2121                name: Set("Apple Pie".to_owned()),
2122            }
2123        );
2124
2125        let mut cake: cake::ActiveModel = Default::default();
2126        cake.set_from_json(json!({
2127            "name": "Apple Pie",
2128        }))
2129        .unwrap();
2130        assert_eq!(
2131            cake,
2132            cake::ActiveModel {
2133                id: NotSet,
2134                name: Set("Apple Pie".to_owned()),
2135            }
2136        );
2137    }
2138
2139    #[test]
2140    #[cfg(feature = "with-json")]
2141    fn test_active_model_set_from_json_2() -> Result<(), DbErr> {
2142        let mut fruit: fruit::ActiveModel = Default::default();
2143
2144        fruit.set_from_json(json!({
2145            "name": "Apple",
2146        }))?;
2147        assert_eq!(
2148            fruit,
2149            fruit::ActiveModel {
2150                id: ActiveValue::NotSet,
2151                name: ActiveValue::Set("Apple".to_owned()),
2152                cake_id: ActiveValue::NotSet,
2153            }
2154        );
2155
2156        assert_eq!(
2157            fruit::ActiveModel::from_json(json!({
2158                "name": "Apple",
2159            }))?,
2160            fruit::ActiveModel {
2161                id: ActiveValue::NotSet,
2162                name: ActiveValue::Set("Apple".to_owned()),
2163                cake_id: ActiveValue::NotSet,
2164            }
2165        );
2166
2167        fruit.set_from_json(json!({
2168            "name": "Apple",
2169            "cake_id": null,
2170        }))?;
2171        assert_eq!(
2172            fruit,
2173            fruit::ActiveModel {
2174                id: ActiveValue::NotSet,
2175                name: ActiveValue::Set("Apple".to_owned()),
2176                cake_id: ActiveValue::Set(None),
2177            }
2178        );
2179
2180        fruit.set_from_json(json!({
2181            "id": null,
2182            "name": "Apple",
2183            "cake_id": 1,
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(Some(1)),
2191            }
2192        );
2193
2194        fruit.set_from_json(json!({
2195            "id": 2,
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        let mut fruit = fruit::ActiveModel {
2209            id: ActiveValue::Set(1),
2210            name: ActiveValue::NotSet,
2211            cake_id: ActiveValue::NotSet,
2212        };
2213        fruit.set_from_json(json!({
2214            "id": 8,
2215            "name": "Apple",
2216            "cake_id": 1,
2217        }))?;
2218        assert_eq!(
2219            fruit,
2220            fruit::ActiveModel {
2221                id: ActiveValue::Set(1),
2222                name: ActiveValue::Set("Apple".to_owned()),
2223                cake_id: ActiveValue::Set(Some(1)),
2224            }
2225        );
2226
2227        Ok(())
2228    }
2229
2230    #[test]
2231    #[cfg(feature = "with-json")]
2232    fn test_active_model_set_from_json_3() -> Result<(), DbErr> {
2233        use crate::*;
2234
2235        let db = MockDatabase::new(DbBackend::Postgres)
2236            .append_exec_results([
2237                MockExecResult {
2238                    last_insert_id: 1,
2239                    rows_affected: 1,
2240                },
2241                MockExecResult {
2242                    last_insert_id: 1,
2243                    rows_affected: 1,
2244                },
2245            ])
2246            .append_query_results([
2247                [fruit::Model {
2248                    id: 1,
2249                    name: "Apple".to_owned(),
2250                    cake_id: None,
2251                }],
2252                [fruit::Model {
2253                    id: 2,
2254                    name: "Orange".to_owned(),
2255                    cake_id: Some(1),
2256                }],
2257            ])
2258            .into_connection();
2259
2260        let mut fruit: fruit::ActiveModel = Default::default();
2261        fruit.set_from_json(json!({
2262            "name": "Apple",
2263        }))?;
2264        fruit.save(&db)?;
2265
2266        let mut fruit = fruit::ActiveModel {
2267            id: Set(2),
2268            ..Default::default()
2269        };
2270        fruit.set_from_json(json!({
2271            "id": 9,
2272            "name": "Orange",
2273            "cake_id": 1,
2274        }))?;
2275        fruit.save(&db)?;
2276
2277        assert_eq!(
2278            db.into_transaction_log(),
2279            [
2280                Transaction::from_sql_and_values(
2281                    DbBackend::Postgres,
2282                    r#"INSERT INTO "fruit" ("name") VALUES ($1) RETURNING "id", "name", "cake_id""#,
2283                    ["Apple".into()],
2284                ),
2285                Transaction::from_sql_and_values(
2286                    DbBackend::Postgres,
2287                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
2288                    ["Orange".into(), 1i32.into(), 2i32.into()],
2289                ),
2290            ]
2291        );
2292
2293        Ok(())
2294    }
2295
2296    #[test]
2297    fn test_active_model_is_changed() {
2298        let mut fruit: fruit::ActiveModel = Default::default();
2299        assert!(!fruit.is_changed());
2300
2301        fruit.set(fruit::Column::Name, "apple".into());
2302        assert!(fruit.is_changed());
2303
2304        let mut fruit = fruit::Model {
2305            id: 1,
2306            name: "".into(),
2307            cake_id: None,
2308        };
2309        fruit.set("name".parse().unwrap(), "orange".into());
2310        assert_eq!(fruit.name, "orange");
2311    }
2312
2313    #[test]
2314    fn test_reset_1() {
2315        assert_eq!(
2316            fruit::Model {
2317                id: 1,
2318                name: "Apple".into(),
2319                cake_id: None,
2320            }
2321            .into_active_model(),
2322            fruit::ActiveModel {
2323                id: Unchanged(1),
2324                name: Unchanged("Apple".into()),
2325                cake_id: Unchanged(None)
2326            },
2327        );
2328
2329        assert_eq!(
2330            fruit::Model {
2331                id: 1,
2332                name: "Apple".into(),
2333                cake_id: None,
2334            }
2335            .into_active_model()
2336            .reset_all(),
2337            fruit::ActiveModel {
2338                id: Set(1),
2339                name: Set("Apple".into()),
2340                cake_id: Set(None)
2341            },
2342        );
2343
2344        assert_eq!(
2345            fruit::Model {
2346                id: 1,
2347                name: "Apple".into(),
2348                cake_id: Some(2),
2349            }
2350            .into_active_model(),
2351            fruit::ActiveModel {
2352                id: Unchanged(1),
2353                name: Unchanged("Apple".into()),
2354                cake_id: Unchanged(Some(2)),
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            .reset_all(),
2366            fruit::ActiveModel {
2367                id: Set(1),
2368                name: Set("Apple".into()),
2369                cake_id: Set(Some(2)),
2370            },
2371        );
2372    }
2373
2374    #[test]
2375    fn test_reset_2() -> Result<(), DbErr> {
2376        use crate::*;
2377
2378        let db = MockDatabase::new(DbBackend::Postgres)
2379            .append_exec_results(vec![
2380                MockExecResult {
2381                    last_insert_id: 1,
2382                    rows_affected: 1,
2383                },
2384                MockExecResult {
2385                    last_insert_id: 1,
2386                    rows_affected: 1,
2387                },
2388            ])
2389            .append_query_results(vec![
2390                vec![fruit::Model {
2391                    id: 1,
2392                    name: "Apple".to_owned(),
2393                    cake_id: None,
2394                }],
2395                vec![fruit::Model {
2396                    id: 1,
2397                    name: "Apple".to_owned(),
2398                    cake_id: None,
2399                }],
2400            ])
2401            .into_connection();
2402
2403        fruit::Model {
2404            id: 1,
2405            name: "Apple".into(),
2406            cake_id: None,
2407        }
2408        .into_active_model()
2409        .update(&db)?;
2410
2411        fruit::Model {
2412            id: 1,
2413            name: "Apple".into(),
2414            cake_id: None,
2415        }
2416        .into_active_model()
2417        .reset_all()
2418        .update(&db)?;
2419
2420        assert_eq!(
2421            db.into_transaction_log(),
2422            vec![
2423                Transaction::from_sql_and_values(
2424                    DbBackend::Postgres,
2425                    r#"SELECT "fruit"."id", "fruit"."name", "fruit"."cake_id" FROM "fruit" WHERE "fruit"."id" = $1 LIMIT $2"#,
2426                    vec![1i32.into(), 1u64.into()],
2427                ),
2428                Transaction::from_sql_and_values(
2429                    DbBackend::Postgres,
2430                    r#"UPDATE "fruit" SET "name" = $1, "cake_id" = $2 WHERE "fruit"."id" = $3 RETURNING "id", "name", "cake_id""#,
2431                    vec!["Apple".into(), Option::<i32>::None.into(), 1i32.into()],
2432                ),
2433            ]
2434        );
2435
2436        Ok(())
2437    }
2438
2439    #[test]
2440    fn test_active_model_default_values() {
2441        assert_eq!(
2442            fruit::ActiveModel::default_values(),
2443            fruit::ActiveModel {
2444                id: Set(0),
2445                name: Set("".into()),
2446                cake_id: Set(None),
2447            },
2448        );
2449
2450        assert_eq!(
2451            lunch_set::ActiveModel::default_values(),
2452            lunch_set::ActiveModel {
2453                id: Set(0),
2454                name: Set("".into()),
2455                tea: NotSet,
2456            },
2457        );
2458    }
2459
2460    #[test]
2461    fn test_active_model_set_parent_key() {
2462        let mut fruit = fruit::Model {
2463            id: 2,
2464            name: "F".into(),
2465            cake_id: None,
2466        }
2467        .into_active_model();
2468
2469        let cake = cake::Model {
2470            id: 4,
2471            name: "C".into(),
2472        }
2473        .into_active_model();
2474
2475        fruit.set_parent_key(&cake).unwrap();
2476
2477        assert_eq!(
2478            fruit,
2479            fruit::ActiveModel {
2480                id: Unchanged(2),
2481                name: Unchanged("F".into()),
2482                cake_id: Set(Some(4)),
2483            }
2484        );
2485
2486        assert!(fruit.clear_parent_key::<cake::Entity>().unwrap());
2487
2488        assert_eq!(
2489            fruit,
2490            fruit::ActiveModel {
2491                id: Unchanged(2),
2492                name: Unchanged("F".into()),
2493                cake_id: Set(None),
2494            }
2495        );
2496
2497        let mut cake_filling = cake_filling::ActiveModel::new();
2498
2499        cake_filling.set_parent_key(&cake).unwrap();
2500
2501        assert_eq!(
2502            cake_filling,
2503            cake_filling::ActiveModel {
2504                cake_id: Set(4),
2505                filling_id: NotSet,
2506            }
2507        );
2508    }
2509}