1

私は列挙型を持っています:

enum Role {
    Administrator,
    Sponsor,
    Bot,
}

私のデータベースには、次のような「ロール」というテーブルがあります。

| user_id | administrator | sponsor | bot   |
|---------|---------------|---------|-------|
| 0       | true          | false   | false |
| 1       | false         | false   | false |
| 2       | false         | true    | true  |

生の SQL クエリではなくDieselRoleを使用しているときに、データベースで一致を実行し、対応する列を取得するにはどうすればよいですか?

ロールに一致するメソッドから Diesel 式を返すことはできますが、insert ステートメントでは機能しません。

#[macro_use]
extern crate diesel;

use diesel::{
    mysql::{Mysql, MysqlConnection},
    sql_types::{Bool, Nullable},
    BoxableExpression, Connection, ExpressionMethods, RunQueryDsl,
};
use schema::{roles, users};
use models::{NewUser};

use std::error::Error;

mod schema {
    table! {
        roles (user_id) {
            id -> Unsigned<Bigint>,
            user_id -> Unsigned<Bigint>,
            administrator -> Nullable<Bool>,
            sponsor -> Nullable<Bool>,
            bot -> Nullable<Bool>,
        }
    }

    table! {
        users (id) {
            id -> Unsigned<Bigint>,
            username -> Nullable<Varchar>,
        }
    }

    allow_tables_to_appear_in_same_query!(
        roles,
        users,
    );
}

mod models {
    use super::schema::users;

    #[derive(Insertable, PartialEq, Debug, Default)]
    #[table_name = "users"]
    pub struct NewUser<'a> {
        username: &'a str,
    }

    impl<'a> NewUser<'a> {
        pub fn new(username: &'a str) -> Self {
            Self {
                username
            }
        }
    }
}

enum Role {
    Administrator,
    Sponsor,
    Bot,
}

impl From<&Role> for Box<dyn BoxableExpression<roles::table, Mysql, SqlType = Nullable<Bool>>> {
    fn from(r: &Role) -> Self {
        match r {
            Role::Administrator => Box::new(roles::dsl::administrator),
            Role::Sponsor => Box::new(roles::dsl::sponsor),
            Role::Bot => Box::new(roles::dsl::bot),
        }
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let conn = MysqlConnection::establish("mysql://localhost/stquestion")?;

    diesel::replace_into(users::table)
        .values(&NewUser::new("test_account"))
        .execute(&conn)?;
    diesel::replace_into(roles::table)
        .values((
            roles::dsl::user_id.eq(1),
            <&Role as Into<
                Box<dyn BoxableExpression<roles::table, Mysql, SqlType = Nullable<Bool>>>,
            >>::into(&Role::Administrator)
            .eq(true),
        ))
        .execute(&conn)?;

    Ok(())
}

上記のコードでは、次のコンパイル エラーが発生します。

error[E0277]: the trait bound `std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::
schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool
>>>: diesel::query_source::Column` is not satisfied
  --> src/main.rs:36:17
   |
36 |           .values((
   |  _________________^
37 | |             roles::dsl::user_id.eq(1),
38 | |             <&Role as Into<
39 | |                 Box<dyn BoxableExpression<roles::table, Mysql, SqlType = Nullable<Bool>>>,
40 | |             >>::into(&Role::Administrator)
41 | |             .eq(true),
42 | |         ))
   | |_________^ the trait `diesel::query_source::Column` is not implemented for `std::boxed::Box<dyn diesel::expr
ession::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType =
diesel::sql_types::Nullable<diesel::sql_types::Bool>>>`
   |
   = note: required because of the requirements on the impl of `diesel::insertable::Insertable<stackoverflow_quest
ions::schema::roles::table>` for `diesel::expression::operators::Eq<std::boxed::Box<dyn diesel::expression::Boxabl
eExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_ty
pes::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql
_types::Bool>, bool>>`
   = note: required because of the requirements on the impl of `diesel::insertable::Insertable<stackoverflow_quest
ions::schema::roles::table>` for `(diesel::expression::operators::Eq<stackoverflow_questions::schema::roles::colum
ns::user_id, diesel::expression::bound::Bound<diesel::mysql::types::Unsigned<diesel::sql_types::BigInt>, u64>>, di
esel::expression::operators::Eq<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions:
:schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Boo
l>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>)`
>error[E0277]: the trait bound `std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>: diesel::query_source::Column` is not satisfied
  --> src/main.rs:43:10
   |
43 |         .execute(&conn)?;
   |          ^^^^^^^ the trait `diesel::query_source::Column` is not implemented for `std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>`
   |
   = note: required because of the requirements on the impl of `diesel::insertable::InsertValues<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql>` for `diesel::insertable::ColumnInsertValue<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>`
   = note: required because of the requirements on the impl of `diesel::insertable::InsertValues<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql>` for `(diesel::insertable::ColumnInsertValue<stackoverflow_questions::schema::roles::columns::user_id, diesel::expression::bound::Bound<diesel::mysql::types::Unsigned<diesel::sql_types::BigInt>, u64>>, diesel::insertable::ColumnInsertValue<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>)`
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<diesel::mysql::backend::Mysql>` for `diesel::query_builder::insert_statement::ValuesClause<(diesel::insertable::ColumnInsertValue<stackoverflow_questions::schema::roles::columns::user_id, diesel::expression::bound::Bound<diesel::mysql::types::Unsigned<diesel::sql_types::BigInt>, u64>>, diesel::insertable::ColumnInsertValue<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>), stackoverflow_questions::schema::roles::table>`
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<diesel::mysql::backend::Mysql>` for `diesel::query_builder::insert_statement::InsertStatement<stackoverflow_questions::schema::roles::table, diesel::query_builder::insert_statement::ValuesClause<(diesel::insertable::ColumnInsertValue<stackoverflow_questions::schema::roles::columns::user_id, diesel::expression::bound::Bound<diesel::mysql::types::Unsigned<diesel::sql_types::BigInt>, u64>>, diesel::insertable::ColumnInsertValue<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>), stackoverflow_questions::schema::roles::table>, diesel::query_builder::insert_statement::Replace>`
   = note: required because of the requirements on the impl of `diesel::query_dsl::load_dsl::ExecuteDsl<_, diesel::mysql::backend::Mysql>` for `diesel::query_builder::insert_statement::InsertStatement<stackoverflow_questions::schema::roles::table, diesel::query_builder::insert_statement::ValuesClause<(diesel::insertable::ColumnInsertValue<stackoverflow_questions::schema::roles::columns::user_id, diesel::expression::bound::Bound<diesel::mysql::types::Unsigned<diesel::sql_types::BigInt>, u64>>, diesel::insertable::ColumnInsertValue<std::boxed::Box<dyn diesel::expression::BoxableExpression<stackoverflow_questions::schema::roles::table, diesel::mysql::backend::Mysql, SqlType = diesel::sql_types::Nullable<diesel::sql_types::Bool>>>, diesel::expression::bound::Bound<diesel::sql_types::Nullable<diesel::sql_types::Bool>, bool>>), stackoverflow_questions::schema::roles::table>, diesel::query_builder::insert_statement::Replace>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `stackoverflow-questions`.

To learn more, run the command again with --verbose.

この問題の再現可能な例をここに作成しました。

4

1 に答える 1