【发布时间】:2020-11-27 22:54:14
【问题描述】:
我正在构建一个由 Rust 的 Diesel ORM 支持的(喘气的)博客。我希望帖子的 URL 包含其标题的“slug”。因此,帖子应该可以通过 slug 查询。因此,我希望使用 slugify crate 从标题生成 slug,然后将 slug 存储在数据库中帖子表的相应列中。
因为帖子也会有一个由数据库生成的数字 ID,我希望将传入的帖子解析为另一个结构,NewPost。然后NewPost 应该实现 Diesel 的Insertable,以便在数据库中记录一个新帖子,调用生成的insert_into 方法就足够了。但是,它不能简单地派生Insertable,因为需要先生成 slug 属性的值。
一种选择是引入一个中间结构 SluggedNewPost,并为其实现 From<NewPost> 和 Insertable 特征:
struct NewPost<'a> {
title: &'a str,
content: &'a str,
}
#[derive(Insertable)]
#[table_name="posts"]
struct SluggedNewPost<'a> {
title: &'a str,
content: &'a str,
slug: String,
}
impl <'a> From<NewPost<'a>> for SluggedNewPost<'a> {
fn from(newpost: NewPost<'a> ) -> Self {
SluggedNewPost {title: &'a newpost.title,
content: newpost.content,
slug: slugify(newpost.title)}
}
}
这适用于我的有限目的。但是直接在NewPost 上实现Insertable 方法似乎更优雅。我尝试遵循this answer的建议,但失败了,因为我不明白宏扩展生成的代码(例如,取消引用values元组中的id条目的结果是什么?)。
尝试手动实现Insertable 是完全错误的方法吗?还是在这样做时我错过了一些非常容易的东西?看起来这种事情在经济上应该是可行的。
【问题讨论】:
标签: rust insert rust-diesel