# Use sql\_function in a changeset

**URL:** <https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144>\
**Category:** Diesel 2.0\
**Created:** [April 13, 2020, 7:24am UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144 "2020-04-13T07:24:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdrouet](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/jdrouet/32/72_2.png) [@jdrouet](https://discourse.diesel.rs/u/jdrouet)\
**Post date:** [April 13, 2020, 7:24am UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/1 "2020-04-13T07:24:56Z")

</div>

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?

```auto
#[derive(AsChangeset, Debug, Deserialize, Serialize)]
#[table_name="users"]
pub struct UserUpdate {
  name: Option<String>,
  token: Option<Uuid>,
}

```

Thank you in advance 😉

---

<div class="post-metadata">

**Author:** ![weiznich](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/weiznich/32/64_2.png) [@weiznich](https://discourse.diesel.rs/u/weiznich)\
**Post date:** [April 14, 2020, 12:00pm UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/2 "2020-04-14T12:00:09Z")

</div>

That is already possible with the released diesel 1.4.x version.

```auto
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(())
}

```

---

<div class="post-metadata">

**Author:** ![jdrouet](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/jdrouet/32/72_2.png) [@jdrouet](https://discourse.diesel.rs/u/jdrouet)\
**Post date:** [April 14, 2020, 7:25pm UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/3 "2020-04-14T19:25:41Z")

</div>

But how can I make that optional?

And apparently, `sql_function!(fn uuid_generate_v4() -> Uuid);` doesn’t seem to work 🤔

```auto
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

```

---

<div class="post-metadata">

**Author:** ![weiznich](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/weiznich/32/64_2.png) [@weiznich](https://discourse.diesel.rs/u/weiznich)\
**Post date:** [April 15, 2020, 8:46am UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/4 "2020-04-15T08:46:40Z")

</div>

> 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!`](http://docs.diesel.rs/diesel/macro.no_arg_sql_function.html) for this on the latest release.

---

<div class="post-metadata">

**Author:** ![jdrouet](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/jdrouet/32/72_2.png) [@jdrouet](https://discourse.diesel.rs/u/jdrouet)\
**Post date:** [April 15, 2020, 8:01pm UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/5 "2020-04-15T20:01:18Z")

</div>

Well my goal is to update a value only if the field `is_some()`.

My object is the following

```auto
#[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.

---

<div class="post-metadata">

**Author:** ![weiznich](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/weiznich/32/64_2.png) [@weiznich](https://discourse.diesel.rs/u/weiznich)\
**Post date:** [April 16, 2020, 8:24am UTC](https://discourse.diesel.rs/t/use-sql-function-in-a-changeset/144/6 "2020-04-16T08:24:07Z")

</div>

Something like this should work:

```auto
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`
