dongqu4443 2017-04-20 08:48
浏览 844
已采纳

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 09: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条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部