Hi!
I’m trying to update a uuid
in an object by using a sql_function!(fn uuid_generate_v4() -> Uuid);
Is there a way to combine that with a changeset?
#[derive(AsChangeset, Debug, Deserialize, Serialize)]
#[table_name="users"]
pub struct UserUpdate {
name: Option<String>,
token: Option<Uuid>,
}
Thank you in advance
That is already possible with the released diesel 1.4.x version.
sql_function!(fn uuid_generate_v4() -> Uuid);
fn update_user(update: UserUpdate, connection: &PgConnection) -> Result<()> {
diesel::update(update)
.set((update, users::whatever.eq(uuid_generate_v4())))
.execute(connection)?;
Ok(())
}
But how can I make that optional?
And apparently, sql_function!(fn uuid_generate_v4() -> Uuid);
doesn’t seem to work
error: this must repeat at least once
--> $HOME/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.4/src/expression/functions/mod.rs:33:20
|
33 | where $($arg_name: $crate::expression::AsExpression<$arg_type>),+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0425]: cannot find function `uuid_generate_v4` in this scope
--> src/model/user.rs:99:38
|
99 | .set(users::dsl::token.eq(uuid_generate_v4()));
| ^^^^^^^^^^^^^^^^ not found in this scope
But how can I make that optional?
What do you mean by that? Using the provided uuid or generate a new one depending on the value of update.token
? In that case I would just branch depending on that value.
And apparently, sql_function!(fn uuid_generate_v4() → Uuid); doesn’t seem to work
Right, you need to use no_arg_sql_function!
for this on the latest release.
Well my goal is to update a value only if the field is_some()
.
My object is the following
#[derive(AsChangeset, Debug, Deserialize, Serialize)]
#[table_name="users"]
pub struct UserUpdate {
name: Option<String>,
token: Option<bool>,
}
And I want to update the name only when the name exists and only refresh the token when the token is set to true
.
Do you have any solution in mind for that ?
I’ve tried to chain the .set
depending on .is_some()
but this is not really straightforward.
Something like this should work:
fn update_user(update: UserUpdate, connection: &PgConnection) -> Result<()> {
// this will fail if both, name and token are none, so check that case if you don't want to error
diesel::update(users::table)
.set((
update.name.map(|n| users::name.eq(n)),
update.token.map(|_| users::token.eq(uuid_generate_v4))
)).execute(connection)?;
Ok(())
}
Alternatively you can implement AsChangeset
manually to return exactly those values passed to set