yii2 中如何用 model 动态添加 attribute,并且添加新的 attribute 计算公式 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yantze
6.82D
V2EX    PHP

yii2 中如何用 model 动态添加 attribute,并且添加新的 attribute 计算公式

  •  
  •   yantze 2015-07-15 11:17:08 +08:00 9339 次点击
    这是一个创建于 3754 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如数据表B的数据里面记录的是这样:

    distribution.....分配.....NULL
    appoint..........人数.....NULL
    rate5............转化率...distribution/appoint

    数据表A现在要显示distribution和appoint这两个字段,并且现在需要动态的显示一个新的字段rate5,其值来自公式计算的值。

    当用户需要查看这个表的数据的时候,再动态的计算出这些值,这样可以不用写分页和排序,并且代码简洁。

    yii2有一个DynamicModel可以动态添加attribute,但是不支持数据库表。所以这个方法应该不行。

    18 条回复    2015-07-17 22:21:24 +08:00
    picasso250
        1
    picasso250  
       2015-07-15 12:54:39 +08:00   1
    为什么不创建view,然后裸写sql?
    yantze
        2
    yantze  
    OP
       2015-07-15 13:25:38 +08:00
    @picasso250 目前我用的就是这样的方法,但是随着项目的跟进,有可能代码会越来越难维护。
    所以我现在先使用拼接手写sql代码,以后打算重写一个基类,专门做这种model
    justfindu
        3
    justfindu  
       2015-07-15 13:25:59 +08:00   1
    model里面增加一个 function getRate5 ; return distribution/appoint.

    这样就可以用魔法函数 直接 $model->rate5 直接获取了
    yantze
        4
    yantze  
    OP
       2015-07-15 13:35:16 +08:00
    @justfindu 可是如果这样,getRate5函数我也必须动态添加,因为数据库表B的数据也是动态的
    yantze
        5
    yantze  
    OP
       2015-07-15 13:45:58 +08:00
    @justfindu 并且我按照你的方法去做完了,但是使用GridView后,不能自动排序。很可能是因为,AR model排序也是用sql排的,所以,目前最完美的解法,只能是写一个新的基类。
    AsterOcclu
        6
    AsterOcclu  
       2015-07-15 15:58:58 +08:00   1
    @yantze @justfindu 的方法是对的,至于GridView的排序和搜索功能,需要你自己去扩展对应的sort方法。http://www.yiiframework.com/doc-2.0/guide-output-sorting.html
    jarlyyn
        7
    jarlyyn  
       2015-07-15 17:45:58 +08:00
    2不熟。
    但从我的角度来看

    都要自定义表单功能了,还不如直接丢给前端js+api处理,别考虑 gridview了。
    yantze
        8
    yantze  
    OP
       2015-07-16 13:39:09 +08:00
    @jarlyyn 几十万条的数据全部取出来再排序! +_+
    jarlyyn
        9
    jarlyyn  
       2015-07-16 13:50:04 +08:00
    @yantze

    你能不能随便找几个api先看看别人是怎么实现的。
    加个 offset和limit不就能搞定了……
    jarlyyn
        10
    jarlyyn  
       2015-07-16 13:56:02 +08:00   1
    @yantze

    以Yii 1.x为例,我会这么做:

    创建一个api,用user/session认证。

    创建一个formModel,把offset/limit/排序/各种过滤选型都丢在里面,并负责验证。

    通过formModel生成合适的CdbCriteria,用于生成合适的数据。

    以json返回。

    前台用react/underscore来渲染。

    好处是不用动1里蛋疼的要死的gridview。

    稍微复杂点的东西就基本是通过eval来实现,各种排序也是,满蛋疼的。

    自己写前端舒服多了。
    yantze
        11
    yantze  
    OP
       2015-07-17 00:20:51 +08:00
    @jarlyyn 虽然说了这么多,但是还是没有说明Model里面如何动态的添加可排序的新字段。

    这种涉及底层的东西并不是修改model就可以实现的。

    因为yii当初设计model的时候,对于AR model只做了数据库的映射,对于非数据库字段的排序并没有定义SQL排序方法,所以,只能通过重写底层的model来实现的。

    有兴趣可以一起写一个这样的model出来。
    jarlyyn
        12
    jarlyyn  
       2015-07-17 10:25:54 +08:00
    @yantze

    至少在Yii 1.x里,排序不该找Model,

    应该找cdbcriteria.

    可以在model里新建一个scope,用于合并cdbcriteria.

    另外恕我不能 理解 ‘动态的添加可排序的新字段’ 的概念……

    排序一般不是数据库处理的事情吗……
    jarlyyn
        13
    jarlyyn  
       2015-07-17 10:29:58 +08:00
    @yantze

    大概的去看了下2的文档

    2里cdbcriteria对应的概念应该是activequery
    http://www.yiiframework.com/doc-2.0/yii-db-activequery.html
    jarlyyn
        14
    jarlyyn  
       2015-07-17 10:31:19 +08:00
    @yantze
    我觉得你需要的排序这一块的应该找这里:

    http://www.yiiframework.com/doc-2.0/yii-db-querytrait.html#orderBy()-detail
    yantze
        15
    yantze  
    OP
       2015-07-17 13:01:10 +08:00
    @jarlyyn ‘动态的添加可排序的新字段’,比如说,这个数据表里面没有字段rate5,但是现在我要通过model显示这个rate5,现在该怎么办呢?一般直接在model里面申明一个非动态的变量就可以了。

    但是这种变量并没有与数据库链接,所以并不能排序。关于activequery和orderby都是来自AR(activerecord)
    yantze
        16
    yantze  
    OP
       2015-07-17 13:02:32 +08:00
    @yantze ‘申明一个非动态的变量’ 改为 ‘申明一个非静态的变量’
    jarlyyn
        17
    jarlyyn  
       2015-07-17 14:00:18 +08:00
    @yantze

    哪家的model能实现你的这个需求呢?

    这个应该是自定义orderby的参数来做的吧?
    yantze
        18
    yantze  
    OP
       2015-07-17 22:21:24 +08:00
    @jarlyyn 是的,所以我已经先自己拼接sql完成了,不过我觉得应该可以用model实现,只是现在暂时没有这么多的时间。如果以后我能做出来,也许能发布出来。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3766 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:22 PVG 13:22 LAX 22:22 JFK 01:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86