dongqu4443 2017-04-20 16:48
浏览 842
已采纳

Eloquent模型上的自定义字段名称

I have a table posts and this table has some columns like pst_id, pst_title, pst_content, pst_category_id and like that. I wanna represent this fields with some better names on json output, actually I'm trying to remove the prefix pst_ from column names.

I tested multiple ways. At first I tried to make an alias for this columns on DB layer, for example Post::select(['pst_id as id'])->get(). This idea generally is awful, because it makes the column names inconsistent across of the software (each developer may have a convention to naming a field). So I insist to find a way for naming the columns on model layer.

The next solution was for using Accessors and Mutators. Although it covers the problem of previous way, but it's really hard to implement 20 methods for each model! 20x100 ~ 2000 methods!!! :/

The last solution which I tested was about using the mappable feature of https://github.com/jarektkaczyk/eloquence. It's really good, I can put all old fields to $hidden property and add new ones to $appends for showing on output. But this solution also have a problem. If I add all new fields to $appends, when I use select statement for choosing some columns, the non-selected columns will be showed on output with a null value :|. Well, I tried to override mappedselect and parseMappings methods on a base model for adding new names to $appends dynamically, but it doesn't satisfy me. In fact it becomes very tricky on using and I'm not sure that the team can accept it and use it easily.

So that's the problem: "Is there a way for renaming the name of columns on output for eloquent?". GoLang has a very good feature which is called Struct Tags. You can define some tags for your structure, for example like this:

type Post struct {
  Pst_id            int       `json:"id"`
  Pst_title         string    `json:"title"`
  Pst_content       string    `json:"content"`
}

And when you produce a json for a Post structure with json.Marshal, based on tags, it gives you a json like this:

{
  "id": 23,
  "title": "Custom Field Tags for Eloquent",
  "content": "I tried a lot of things, but they are hard. I'm a programmer so I'm lazy! What can I do?",
}

I think we don't have something like this in the php world, but is there any way to use the idea behinds doctrine's annotation for implementing something like tag structure in Go?

Any comments and idea are welcome!

  • 写回答

2条回答 默认 最新

  • douxunwei8259 2017-04-20 17:49
    关注

    First step would be to override a couple methods on those models. The first method is the getAttribute() which is called when you access an attributed of a model so you can access it. You would want to be able to access the attribute without the pst_ prefix so you would do:

    public function getAttribute($key)
    {
        if(array_key_exists($prefixedKey = 'pst_'.$key, $this->attributes)) {
            return $this->attributes[$prefixedKey];
        }
    
        return parent::getAttribute($key);
    }
    

    Then to make sure the keys don't have the prefix when casting to json you would override the attributesToArray() method which is what is called when outputting json and will also respect your $hidden, $visible, $casts and $dates arrays. That would be something like:

    public function attributesToArray()
    {
        $attributes = parent::attributesToArray();
    
        $mutated = [];
        foreach ($attributes as $key => $value) {
            $mutated[preg_replace('/^pst_/', '', $key)] = $value;
        }
    
        return $mutated;
    }
    

    To implement those you can extend the Model class with an abstract class that implements those methods and have your classes extend that base class or create a trait with those methods and have your classes implement that trait.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号