You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Diesel实现通用更新函数时Identifiable trait绑定报错问题

问题根因

你使用的Diesel 1.4.x版本中,派生Identifiable trait时默认仅会为该类型的不可变引用实现trait,不会直接对类型本身生成实现。而你现有函数约束中要求Model: IntoUpdateTarget,该 trait 针对模型实例的实现依赖Model自身实现Identifiable,因此触发了编译报错。

解决方案

方案一:修改通用函数参数为引用(推荐)

调整函数参数和约束,直接接收旧模型的引用,匹配Diesel默认的Identifiable实现范围,同时还能避免不必要的对象克隆:

pub fn update<Model>(
    conn: &PgConnection,
    old_model: &Model, // 旧模型改为引用类型
    mut updated_model: Model,
    user_id: Uuid,
) -> Result<Model, diesel::result::Error>
where
    Model: MetaFields + AsChangeset<Target = <Model as HasTable>::Table> + HasTable + Identifiable,
    // 声明任意生命周期的Model引用都满足IntoUpdateTarget约束
    for<'a> &'a Model: IntoUpdateTarget<Table = <Model as HasTable>::Table>,
    // 声明对应Update语句可以执行查询返回Model
    for<'a> Update<&'a Model, Model>: LoadQuery<PgConnection, Model>
{
    updated_model.update_fields(user_id);
    // 去掉多余的unwrap,直接返回查询结果
    diesel::update(old_model)
        .set(updated_model)
        .get_result(conn)
}

调用时直接传入旧模型的引用即可,不需要再克隆:

common::dao::update(&conn2, &real_marking1[0], marking2_to_update, jwt_token.user_id)

方案二:手动为模型实现自身的Identifiable

如果确实需要传递旧模型的所有权,可手动为Marking等所有模型补充自身的Identifiable实现:

impl Identifiable for Marking {
    type Id = Uuid;
    fn id(&self) -> Self::Id {
        self.uuid
    }
}

额外优化建议

你当前MetaFields实现中的self.ver.unwrap()存在panic风险,若数据库中某条记录的ver字段为NULL会直接崩溃,建议调整为带默认值的写法:

self.ver = Option::from(self.ver.unwrap_or(0) + 1);

内容的提问来源于stack exchange,提问作者Dmitrii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:45:05