drogon icon indicating copy to clipboard operation
drogon copied to clipboard

How about add custom AbstractModel class for user 's custom?

Open HadesD opened this issue 3 years ago • 7 comments

Inspired from laravel, can you add AbstractModel.h + AbstractModel.cc to models folder (when create new app), and auto extends to it when auto gen models orm? With this abstract, user can freely to add their custom to each model

HadesD avatar Dec 05 '21 15:12 HadesD

Could Mapper::paginate() in #1112 solve your problem?

hwc0919 avatar Dec 06 '21 04:12 hwc0919

@hwc0919 yeah thanks, but I think you should add a custom-able for end-user to modify what they want

HadesD avatar Dec 06 '21 09:12 HadesD

Could you give a example on what you refering by 'user custom'? https://github.com/drogonframework/drogon/blob/d18740d4bca53670c55e1a3bbdb1b84694eda9f4/drogon_ctl/templates/model_h.csp#L560-L564 These things can be done for all models with a simple template function, which can be written anywhere you want. In fact, I think they are all business related and should not be appeared in orm level.

hwc0919 avatar Dec 06 '21 09:12 hwc0919

@hwc0919 Thanks, I think atm, we not need an abstract model. But should have a way for end-user modify orm Model Like EAV ( https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model ), or custom output for toJson

HadesD avatar Dec 06 '21 14:12 HadesD

You could make some templates like the Mapper template to approach the aim, for your case, just move the code you added to the model.csp outside, make it a function template:

    template <class T>
    std::shared_ptr<Json::Value> paginate(const drogon::orm::Criteria &criteria, int limit, int page)
    {
        if (page <= 0)
        {
            page = 1;
        }
        auto resJson = std::make_shared<Json::Value>();

        auto dbClientPtr = drogon::app().getDbClient()->newTransaction();
        drogon::orm::Mapper<T> tblMapper(dbClientPtr);
        (*resJson)["current_page"] = page;
        (*resJson)["total"] = static_cast<uint>(tblMapper.count(criteria));
        (*resJson)["per_page"] = limit;
        (*resJson)["data"] = Json::Value(Json::arrayValue);
        auto &resJsonData = (*resJson)["data"];
        auto rcb = tblMapper
                        .orderBy(T::Cols::_created_at, drogon::orm::SortOrder::DESC)
                        .limit(limit)
                        .offset(limit * (page - 1))
                        .findBy(criteria);
        for (const auto &row : rcb)
        {
            resJsonData.append(row.toJson());
        }

        return resJson;
    }

This static polymorphic technology can help you expand the capabilities of models

an-tao avatar Dec 06 '21 14:12 an-tao

The model class generated by drogon_ctl create model is just a helper. If you need some custom feature, you can just modified the source file, or add some standalone functions. No need of polymorphic at all. For example you can modify the toJson() method to ignore some fields or add some transformation, or you can create a function toCustomJson(const Model &) to meet your own need.

hwc0919 avatar Dec 06 '21 14:12 hwc0919

@hwc0919 these model are auto-generated, so, as an end-user 's view-point, I'm scare about modify content of it also, these file are updated after each update of drogon, so i think we should not modify it directly image

HadesD avatar Dec 06 '21 16:12 HadesD