fetch処理前提
例えば、select * from ...
と全カラム取得する場合、bindするmodelの定義は
#[derive(Debug, Clone, Queryable, Identifiable)] pub struct Account { pub id: String, pub name: String, pub email: String, pub password: String, pub avatar: String, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, }
のようにQueryableを指定して、dslに定義された全カラムのフィールド定義が必要。で、この時、insert時はcreated_atなんかをDBに定義したdefault値を使用したい。なんてケース。
insert用のモデルとfetch用のモデルを分ける
insert用のモデルとfetch用のモデルを分けるのが楽。
#[derive(Debug, Clone, Queryable, Identifiable)] pub struct Account { pub id: String, pub name: String, pub email: String, pub password: String, pub avatar: String, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, } #[derive(Default, Debug, Clone, Insertable)] #[table_name = "accounts"] pub struct NewAccount { pub id: String, pub name: String, pub email: String, pub password: String, pub avatar: String, }
NewAccount
はどのテーブルへのInsertable
かがわからないので、#[table_name = "accounts"]
を指定します。
これで単純に使い分けを行えばよい。
insert
let new_account = NewAccount{ ... }; insert_into(dsl::accounts) .values(account) .returning(dsl::id) .get_result(&conn)
fetch
dsl::accounts .filter(dsl::email.eq(email)) .load::<Account>(&conn)
loadメソッドのNone時のassert確認
少しハマったので記録しておきます。
loadメソッドはQueryResult<Vec<T>>
型が返されるんだけど、not found resultのテスト時に
assert_eq!( result.unwrap().first(), None );
とは書けなくて、
assert!( result.unwrap().first().is_none() );
と書くことで確認できる。