pub trait ActiveModelTrait: Clone + Debug {
    type Entity: EntityTrait;

Show 14 methods fn take(
        &mut self,
        c: <Self::Entity as EntityTrait>::Column
    ) -> ActiveValue<Value>; fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>; fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value); fn not_set(&mut self, c: <Self::Entity as EntityTrait>::Column); fn is_not_set(&self, c: <Self::Entity as EntityTrait>::Column) -> bool; fn default() -> Self; fn get_primary_key_value(&self) -> Option<ValueTuple> { ... } fn insert<'a, 'async_trait, C>(
        self,
        db: &'a C
    ) -> Pin<Box<dyn Future<Output = Result<<Self::Entity as EntityTrait>::Model, DbErr>> + Send + 'async_trait>>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a + Send + 'async_trait,
        C: ConnectionTrait + 'async_trait,
        'a: 'async_trait
, { ... } fn update<'a, 'async_trait, C>(
        self,
        db: &'a C
    ) -> Pin<Box<dyn Future<Output = Result<<Self::Entity as EntityTrait>::Model, DbErr>> + Send + 'async_trait>>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a + Send + 'async_trait,
        C: ConnectionTrait + 'async_trait,
        'a: 'async_trait
, { ... } fn save<'a, 'async_trait, C>(
        self,
        db: &'a C
    ) -> Pin<Box<dyn Future<Output = Result<Self, DbErr>> + Send + 'async_trait>>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a + Send + 'async_trait,
        C: ConnectionTrait + 'async_trait,
        'a: 'async_trait
, { ... } fn delete<'a, 'async_trait, C>(
        self,
        db: &'a C
    ) -> Pin<Box<dyn Future<Output = Result<DeleteResult, DbErr>> + Send + 'async_trait>>
    where
        Self: ActiveModelBehavior + 'a + Send + 'async_trait,
        C: ConnectionTrait + 'async_trait,
        'a: 'async_trait
, { ... } fn set_from_json(&mut self, json: Value) -> Result<(), DbErr>
    where
        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self> + Deserialize<'de>
, { ... } fn from_json(json: Value) -> Result<Self, DbErr>
    where
        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self> + Deserialize<'de>
, { ... } fn is_changed(&self) -> bool { ... }
}
Expand description

A Trait for ActiveModel to perform Create, Update or Delete operation. The type must also implement the EntityTrait. See module level docs crate::entity for a full example

Required Associated Types§

The Entity this ActiveModel belongs to

Required Methods§

Get a mutable ActiveValue from an ActiveModel

Get a immutable ActiveValue from an ActiveModel

Set the Value into an ActiveModel

Set the state of an ActiveValue to the not set state

Check the state of a ActiveValue

The default implementation of the ActiveModel

Provided Methods§

Get the primary key of the ActiveModel

Examples found in repository?
src/query/insert.rs (line 120)
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    pub fn add<M>(mut self, m: M) -> Self
    where
        M: IntoActiveModel<A>,
    {
        let mut am: A = m.into_active_model();
        self.primary_key =
            if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {
                am.get_primary_key_value()
            } else {
                None
            };
        let mut columns = Vec::new();
        let mut values = Vec::new();
        let columns_empty = self.columns.is_empty();
        for (idx, col) in <A::Entity as EntityTrait>::Column::iter().enumerate() {
            let av = am.take(col);
            let av_has_val = av.is_set() || av.is_unchanged();
            if columns_empty {
                self.columns.push(av_has_val);
            } else if self.columns[idx] != av_has_val {
                panic!("columns mismatch");
            }
            if av_has_val {
                columns.push(col);
                values.push(cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col));
            }
        }
        self.query.columns(columns);
        self.query.values_panic(values);
        self
    }
More examples
Hide additional examples
src/executor/update.rs (line 117)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
async fn exec_update_and_return_updated<A, C>(
    mut query: UpdateStatement,
    model: A,
    db: &C,
) -> Result<<A::Entity as EntityTrait>::Model, DbErr>
where
    A: ActiveModelTrait,
    C: ConnectionTrait,
{
    match db.support_returning() {
        true => {
            let returning = Query::returning().exprs(
                <A::Entity as EntityTrait>::Column::iter()
                    .map(|c| cast_enum_as_text(Expr::col(c), &c)),
            );
            query.returning(returning);
            let db_backend = db.get_database_backend();
            let found: Option<<A::Entity as EntityTrait>::Model> =
                SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
                    db_backend.build(&query),
                )
                .one(db)
                .await?;
            // If we got `None` then we are updating a row that does not exist.
            match found {
                Some(model) => Ok(model),
                None => Err(DbErr::RecordNotFound(
                    "None of the database rows are affected".to_owned(),
                )),
            }
        }
        false => {
            // If we updating a row that does not exist then an error will be thrown here.
            Updater::new(query).check_record_exists().exec(db).await?;
            let primary_key_value = match model.get_primary_key_value() {
                Some(val) => FromValueTuple::from_value_tuple(val),
                None => return Err(DbErr::UpdateGetPrimaryKey),
            };
            let found = <A::Entity as EntityTrait>::find_by_id(primary_key_value)
                .one(db)
                .await?;
            // If we cannot select the updated row from db by the cached primary key
            match found {
                Some(model) => Ok(model),
                None => Err(DbErr::RecordNotFound(
                    "Failed to find updated item".to_owned(),
                )),
            }
        }
    }
}

Perform an INSERT operation on the ActiveModel

Example (Postgres)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};

assert_eq!(
    apple.insert(&db).await?,
    cake::Model {
        id: 15,
        name: "Apple Pie".to_owned(),
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#,
        vec!["Apple Pie".into()]
    )]
);
Example (MySQL)
use sea_orm::{entity::*, query::*, tests_cfg::cake};

let apple = cake::ActiveModel {
    name: Set("Apple Pie".to_owned()),
    ..Default::default()
};

assert_eq!(
    apple.insert(&db).await?,
    cake::Model {
        id: 15,
        name: "Apple Pie".to_owned(),
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
            vec!["Apple Pie".into()]
        ),
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?"#,
            vec![15.into(), 1u64.into()]
        )
    ]
);
Examples found in repository?
src/entity/active_model.rs (line 425)
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    async fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a,
        C: ConnectionTrait,
    {
        let mut is_update = true;
        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {
            let col = key.into_column();
            if self.is_not_set(col) {
                is_update = false;
                break;
            }
        }
        let res = if !is_update {
            self.insert(db).await
        } else {
            self.update(db).await
        }?;
        Ok(res.into_active_model())
    }

Perform the UPDATE operation on an ActiveModel

Example (Postgres)
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(1),
    name: Set("Orange".to_owned()),
    ..Default::default()
};

assert_eq!(
    orange.update(&db).await?,
    fruit::Model {
        id: 1,
        name: "Orange".to_owned(),
        cake_id: None,
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 RETURNING "id", "name", "cake_id""#,
        vec!["Orange".into(), 1i32.into()]
    )]);
Example (MySQL)
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(1),
    name: Set("Orange".to_owned()),
    ..Default::default()
};

assert_eq!(
    orange.update(&db).await?,
    fruit::Model {
        id: 1,
        name: "Orange".to_owned(),
        cake_id: None,
    }
);

assert_eq!(
    db.into_transaction_log(),
    vec![
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?"#,
            vec!["Orange".into(), 1i32.into()]
        ),
        Transaction::from_sql_and_values(
            DbBackend::MySql,
            r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
            vec![1i32.into(), 1u64.into()]
        )]);
Examples found in repository?
src/entity/active_model.rs (line 427)
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    async fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
    where
        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        Self: ActiveModelBehavior + 'a,
        C: ConnectionTrait,
    {
        let mut is_update = true;
        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {
            let col = key.into_column();
            if self.is_not_set(col) {
                is_update = false;
                break;
            }
        }
        let res = if !is_update {
            self.insert(db).await
        } else {
            self.update(db).await
        }?;
        Ok(res.into_active_model())
    }

Insert the model if primary key is NotSet, update otherwise. Only works if the entity has auto increment primary key.

Delete an active model by its primary key

Example
use sea_orm::{entity::*, query::*, tests_cfg::fruit};

let orange = fruit::ActiveModel {
    id: Set(3),
    ..Default::default()
};

let delete_result = orange.delete(&db).await?;

assert_eq!(delete_result.rows_affected, 1);

assert_eq!(
    db.into_transaction_log(),
    vec![Transaction::from_sql_and_values(
        DbBackend::Postgres,
        r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
        vec![3i32.into()]
    )]
);
Examples found in repository?
src/entity/model.rs (line 47)
41
42
43
44
45
46
47
48
    async fn delete<'a, A, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
    where
        Self: IntoActiveModel<A>,
        C: ConnectionTrait,
        A: ActiveModelTrait<Entity = Self::Entity> + ActiveModelBehavior + Send + 'a,
    {
        self.into_active_model().delete(db).await
    }

Set the corresponding attributes in the ActiveModel from a JSON value

Note that this method will not alter the primary key values in ActiveModel.

Create ActiveModel from a JSON value

Examples found in repository?
src/entity/active_model.rs (line 506)
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
    fn set_from_json(&mut self, json: serde_json::Value) -> Result<(), DbErr>
    where
        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:
            serde::de::Deserialize<'de>,
    {
        use crate::Iterable;

        // Backup primary key values
        let primary_key_values: Vec<(<Self::Entity as EntityTrait>::Column, ActiveValue<Value>)> =
            <<Self::Entity as EntityTrait>::PrimaryKey>::iter()
                .map(|pk| (pk.into_column(), self.take(pk.into_column())))
                .collect();

        // Replace all values in ActiveModel
        *self = Self::from_json(json)?;

        // Restore primary key values
        for (col, active_value) in primary_key_values {
            match active_value {
                ActiveValue::Unchanged(v) | ActiveValue::Set(v) => self.set(col, v),
                NotSet => self.not_set(col),
            }
        }

        Ok(())
    }

Return true if any attribute of ActiveModel is Set

Implementors§