Как выполнить дополнительные запросы к базе данных при сериализации значения с помощью Serde? - PullRequest
0 голосов
/ 26 октября 2018

A Program имеет отношение один ко многим с Project. Я ищу идеальный способ включить все проекты в программу при печати ответа JSON.

extern crate rocket_contrib;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;

use rocket_contrib::Json;
use serde_json::Value;

mod schema {
    table! {
        projects (id) {
            id -> Int4,
            title -> Varchar,
            program_id -> Int4,
            is_archived -> Bool,
        }
    }

    table! {
        programs (id) {
            id -> Int4,
            title -> Varchar,
            is_archived -> Bool,
        }
    }
}

fn main() {
    let program = Program::get(id);
    let json_value = Json(json!({ "result": program }));
}

Я смотрел на реализацию пользовательской сериализации:

impl Serialize for Program {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
    }
}

Но у меня нет db::Conn, необходимого для извлечения проектов в этой функции.

Я ищу ответ как:

{ 
    "id": 1,
    "is_archived": false,
    "title": "Program 1",
    "projects": [{
      "id": 2,
      "is_archived": false,
       "title": "Project 1"
    }]
}

1 Ответ

0 голосов
/ 27 октября 2018

Практический ответ: не . Сериализация значения не должна включать произвольные вызовы базы данных, она должна только сериализовать . Создайте структуру для хранения всех данных:

#[derive(Serialize)]
struct ProgramAndProjects {
    #[serde(flatten)]
    program: Program,
    projects: Vec<Project>,
}

Затем напишите функцию, которая заполняет эту структуру, выполняя необходимые запросы к базе данных, и напрямую сериализует результат.

Это также дает огромное преимущество, так как является гораздо более тестируемым.


Как говорится, можно сделать, но, скорее всего, оно того не стоит. Вы можете вставить соединение с базой данных в Program (или создать новый тип с соединением и Program), а затем использовать соединение во время сериализации.

Смотри также:

...