2019-07-25 15:18:35 2608次浏览 5条回答 0 悬赏 20 金钱

继承 ActiveRecord 类并重写父类的 fields() 方法后使用了 fields 中的格式化数据和 unset 的变量都可以实现,但是 ->with(['content']) 是关联不到相关表的数据的,如果是使用 asArray() 转换为数组后是可以查到关联数据表中的数据,但是是数组了,最后就调用不了 fields() 方法啦。该怎么办才既能得到关联表的数据也能使用 fields() 中格式化输出的数据,请大佬指点(以下是相关代码)

public function getAllLines(){
    $lines = self::find()
        ->with(['content','extend','details'])
        ->orderBy('addtime Desc')
        //->asArray()
        ->all();
    return $lines;
}
public function getContent(){
    return $this->hasOne(LineContent::className(),['line_id'=>'id']);
}
public function fields(){
    $fields = parent::fields();
    unset($fields['title']);
    $fields['addtime'] = function (){
            return date('Y-m-d H:i:s',$this->addtime);
        };
    return $fields;
}
//注释掉asArray()后的结果(走了fields()后,无title,时间戳也能格式化输出,但是也无关联的content数据)
{
    "id": 1,
    "seotitle": null,
    "startcity_id": 1,
    "startpro_id": 1,
    "startcounty_id": null,
    "start_place_detail": "开团详细",
    "over_place_detail": "目的地详细",
    "addtime": "2019-07-25 09:40:23",
}
//使用asArray()后(感觉没有走fields后有title,时间戳也未格式化,有关联的content数据)
{
    "id": "1",
    "title": "线路标题",//并没有走fields方法去掉改行
    "seotitle": null,
    "startcity_id": "1",
    "startpro_id": "1",
    "startcounty_id": null,
    "start_place_detail": "开团详细",
    "over_place_detail": "目的地详细",
    "addtime": "1564018823",
    "content": {
        "id": "1",
        "reserve": "预定须知",
        "change": "退改规则",
        "special": "特殊人群",
        "prompt": "温馨提示",
        "line_id": "1"
    }
}

怎么能即使用 fields()去掉或者格式化相关的数据, 也能得到 with 关联的数据表的相关数据,求大佬们指点一下,先谢谢啦

  • 回答于 2019-07-25 16:56 举报

    碰巧今天我也遇到这个问题,->asArray()fields() 方法不能同时使用,最后是只用 fields 方法,不使用 ->asArray(); 我只需要关联表里的一个 name 字段,并且去除 driver_installed_num 字段。

    public function fields()
    {
        $fields=parent::fields();
        $fields['name']=function($model){
            return ($store=$model->store) ? $store->name : '';
        };
        unset($fields['driver_installed_num']);
        return $fields;
    }
    
    觉得很赞
  • 回答于 2019-07-25 18:36 举报

    这样写:

    $lines = self::find()
           ->with(['content' => function($query) {
              $query->select(["id", "reserve", "change", ...]);
           }])
           ->with(['extend' => function($query) {
              $query->select([...]);
           }])
           ->with(['details' => function($query) {
              $query->select([...]);
           }])
           ->orderBy('addtime Desc')
           ->asArray()
           ->all();
    
    1 条回复
    回复于 2019-07-26 09:00 回复

    大佬,这个你亲测有效嘛?这样不还是没有走fields()方法嘛,(content的内容是有)没有unset掉指定的字段,我是希望既能走fields又能使用with获取其他关联表的数据

  • 回答于 2019-07-26 03:13 举报

    可以查看下我之前的提问:https://www.yiichina.com/question/4299
    也许对你有帮助!

    1 条回复
    回复于 2019-07-26 09:04 回复

    看了,看不懂

  • 回答于 2019-07-26 15:48 举报

    这样,别 asArray 了,自己用 ArrayHelper::toArray 生成数组,略麻烦

    ArrayHelper::toArray($lines, ['app\models\Lines' => ['id', 'seotitle', ..., 'content' => function($a) {
       return [
          'id' => $a->content->id,
          'reserve' => $a->content->reserve,
         ....
       ]
    }]]);
    
  • 回答于 2019-07-30 11:40 举报

    你把简单的问题搞复杂了。 RESTfull 获取关联表信息通过配置 extraFields() 就能实现,不必使用 with(), joinWith(), 更不必使用 asArray(), REST apis 有一套自己的处理逻辑。

    你声明的 getAllLines() 方法在哪调用?你上面的 JSON 输出对应的 url (endpoint) 又是什么?

您需要登录后才可以回答。登录 | 立即注册
零零零
主管

零零零

注册时间:2018-07-26
最后登录:2024-10-30
在线时长:18小时29分
  • 粉丝1
  • 金钱465
  • 威望0
  • 积分645

热门问题