# Conditional query: Issues with boxing and deleting

**URL:** <https://discourse.diesel.rs/t/conditional-query-issues-with-boxing-and-deleting/96>\
**Category:** Uncategorized\
**Created:** [June 28, 2019, 5:25pm UTC](https://discourse.diesel.rs/t/conditional-query-issues-with-boxing-and-deleting/96 "2019-06-28T17:25:06Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Y0hy0h](https://avatars.discourse-cdn.com/v4/letter/y/f07891/32.png) [@Y0hy0h](https://discourse.diesel.rs/u/Y0hy0h)\
**Post date:** [June 28, 2019, 5:25pm UTC](https://discourse.diesel.rs/t/conditional-query-issues-with-boxing-and-deleting/96/1 "2019-06-28T17:25:06Z")

</div>

Depending on some settings, I want to filter out the occurrences of an event. Because I have boxed the query, it doesn’t let me use it to delete them. The code in question is available at [https://github.com/Y0hy0h/lindyhop-aachen/pull/41](https://github.com/Y0hy0h/lindyhop-aachen/pull/41).

There might be a better approach to creating the conditional query. Any ideas are welcome.

Part of the model:

```auto
#[derive(Queryable, Insertable, Debug, Identifiable, Clone, PartialEq, AsChangeset)]
#[table_name = "events"]
pub struct SqlEvent {
    pub id: SqlId<Event>,
    pub title: String,
    pub teaser: String,
    pub description: String,
}

#[derive(
    Queryable, Insertable, Clone, Debug, Identifiable, PartialEq, AsChangeset, Associations,
)]
#[belongs_to(SqlEvent, foreign_key = "event_id")]
#[belongs_to(SqlLocation, foreign_key = "location_id")]
#[table_name = "occurrences"]
pub struct SqlOccurrence {
    pub id: SqlId<Occurrence>,
    pub event_id: SqlId<Event>,
    pub start: NaiveDateTime,
    pub duration: i32,
    pub location_id: SqlId<Location>,
}

```

The last line of [this function](https://github.com/Y0hy0h/lindyhop-aachen/pull/41/files#diff-7f6d9b79a37a732d67f0d61f69210236R406)’s excerpt is causing errors:

```auto
use db::schema::occurrences::dsl::start;
let mut associated_occurrences = SqlOccurrence::belonging_to(&sql_previous).into_boxed();
if let Some(datetime) = filter.after {
    associated_occurrences= associated_occurrences.filter(start.gt(datetime));
}
if let Some(datetime) = filter.before {
    associated_occurrences= associated_occurrences.filter(start.lt(datetime));
}
let previous_occurrences: Vec<OccurrenceWithLocation> = associated_occurrences
    .load::<SqlOccurrence>(&*self.0)?
    .into_iter()
    .map(|sql_occurrence| {
        let (_, occurrence) = sql_occurrence.into(); // I have a From implementation that converts the SqlOccurrence into (Id<Occurrence>, Occurrence), which are user-facing types.

        occurrence
    })
    .collect();

diesel::delete(associated_occurrences).execute(&*self.0)?;

```

The errors are:

```auto
error[E0277]: the trait bound `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Binary, diesel::sql_types::Binary, diesel::sql_types::Timestamp, diesel::sql_types::Integer, diesel::sql_types::Binary), store::db::schema::occurrences::table, diesel::sqlite::Sqlite>: diesel::Identifiable` is not satisfied
   --> src\store\mod.rs:406:9
    |
406 | diesel::delete(associated_occurrences).execute(&*self.0)?;
    | ^^^^^^^^^^^^^^ the trait `diesel::Identifiable` is not implemented
for `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Binary,
diesel::sql_types::Binary, diesel::sql_types::Timestamp, diesel::sql_types::Integer, diesel::sql_types::Binary), store::db::schema::occurrences::table, diesel::sqlite::Sqlite>`
    |
    = note: required because of the requirements on the impl of `diesel::query_builder::IntoUpdateTarget` for `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Binary, diesel::sql_types::Binary, diesel::sql_types::Timestamp, diesel::sql_types::Integer, diesel::sql_types::Binary), store::db::schema::occurrences::table, diesel::sqlite::Sqlite>`
    = note: required by `diesel::delete`

error[E0277]: the trait bound `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Binary, diesel::sql_types::Binary, diesel::sql_types::Timestamp, diesel::sql_types::Integer, diesel::sql_types::Binary), store::db::schema::occurrences::table, diesel::sqlite::Sqlite>: diesel::associations::HasTable` is not satisfied
   --> src\store\mod.rs:406:9
    |
406 | diesel::delete(associated_occurrences).execute(&*self.0)?;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::associations::HasTable` is not implemented for `diesel::query_builder::BoxedSelectStatement<'_, (diesel::sql_types::Binary, diesel::sql_types::Binary, diesel::sql_types::Timestamp, diesel::sql_types::Integer, diesel::sql_types::Binary), store::db::schema::occurrences::table, diesel::sqlite::Sqlite>`

```

---

<div class="post-metadata">

**Author:** ![Y0hy0h](https://avatars.discourse-cdn.com/v4/letter/y/f07891/32.png) [@Y0hy0h](https://discourse.diesel.rs/u/Y0hy0h)\
**Post date:** [June 29, 2019, 10:14pm UTC](https://discourse.diesel.rs/t/conditional-query-issues-with-boxing-and-deleting/96/2 "2019-06-29T22:14:20Z")

</div>

Thanks to @weiznich on the [Gitter](https://gitter.im/diesel-rs/diesel?at=5d17c465189e7b4ff0355eb6), I managed to make it work with the following:

```auto
[...]

use db::SqlId;

        let raw_id: SqlId<Event> = item_id.into();
        use db::schema::events::dsl::events;
        let sql_previous = events.find(raw_id.clone()).first::<SqlEvent>(&*self.0)?;

        let associated_occurrences = SqlOccurrence::belonging_to(&sql_previous);
        let previous_occurrences: Vec<OccurrenceWithLocation> = associated_occurrences
            .filter(apply_occurrence_filter(&filter))
            .load::<SqlOccurrence>(&*self.0)?
            .into_iter()
            .map(|sql_occurrence| {
                let (_, occurrence) = sql_occurrence.into();

                occurrence
            })
            .collect();

        diesel::delete(associated_occurrences.filter(apply_occurrence_filter(&filter)))
            .execute(&*self.0)?;

[...]

fn apply_occurrence_filter(
    filter: &OccurrenceFilter,
) -> Box<
    dyn BoxableExpression<
        db::schema::occurrences::table,
        diesel::sqlite::Sqlite,
        SqlType = diesel::sql_types::Bool,
    >,
> {
    use db::schema::occurrences::dsl::*;
    let mut query: Box<
        dyn BoxableExpression<
            db::schema::occurrences::table,
            diesel::sqlite::Sqlite,
            SqlType = diesel::sql_types::Bool,
        >,
    > = Box::new(true.into_sql::<diesel::sql_types::Bool>());
    if let Some(before) = filter.before {
        query = Box::new(query.and(start.lt(before)))
    }
    if let Some(after) = filter.after {
        query = Box::new(query.and(start.gt(after)))
    }

    query
}

```
