【问题标题】:Metadata object handling in Laravel [closed]Laravel 中的元数据对象处理 [关闭]
【发布时间】:2014-10-04 07:23:10
【问题描述】:

我需要使用 Laravel 开发一个自定义表单生成器。

这意味着将有一个 GUI 来选择和自定义 Registration Form 或 Booking Form 等表单。用户应该能够添加/编辑/删除不同的表单控件,将其定义为强制等。

在这里,我在后端处理这个有点困惑。实现这一目标的更好方法是什么?

或者我如何实现一个数据库架构来使用一些元数据表来处理多个项目,比如Wordpress,是否有任何内置的 Laravel 功能来处理这些元对象?

以及insert/update/delete 在这种元数据方法中是如何处理的?

这里的插入应该在元表中只有一行。假设在用户注册时,没有将firstname 和lastname 保存在元表的单独行中,它应该在一行中使用一些像这样的对象。

a:3:{s:9:"firstname";s:10:"irshad.far";s:8:"lastname";s:0:"";s:5:"_meta";a:7:{s:2:"ip";s:10:"14.99.80.3";s:9:"confirmip";s:10:"14.99.80.3";s:11:"confirmtime";d:1407932201;s:8:"signupip";s:10:"14.99.80.3";s:10:"signuptime";d:1407932201;s:4:"lang";s:2:"en";s:4:"form";s:7:"unknown";}}

【问题讨论】:

    标签: php mysql laravel laravel-4 eloquent


    【解决方案1】:

    使用 Laravel 的 Eloquent 关系处理元数据表相当简单。假设您的数据库中有一个 users 表,其中包含:

    id    email    password    created_at    updated_at    deleted_at
    

    如果您想保持简单而不是向您的用户表添加各种额外数据,您可以创建一个 meta 表,然后创建一个链接表 user_meta 将两者联系起来。

    但是,如果您也有一个 posts 表(与 Wordpress 一样)并且您的帖子也需要元数据怎么办?我们可以使用 Laravel Eloquent 关系并创建一些 Polymorphic Relations,而不是创建一个 posts_meta 表来将您的帖子链接到他们的元数据。


    数据库

    这是我们的设置,除了我们的 users 表(上图),我们还有一个 posts 表,其中包含以下字段:

    id    title    content    created_at    updated_at    deleted_at
    

    我们还有我们的 meta 表,它遵循多态关系的准则:

    id      name        value         metable_id      metable_type
    //int   meta key    meta value    post/user id    resource ie post/user
    

    使用它,我们可以将帖子或用户的元数据添加到我们的元表中,如下所示:

    id    name       value      metable_id    metable_type
    ------------------------------------------------------
    1     nickname   Steve      1             User
    2     author     Steve O    1             Post
    

    从数据库中获取此信息所需要做的就是定义我们各自模型中的关系。


    模型

    所以现在我们已经准备好我们的数据库,我们需要使用我们的多态关系设置我们的模型(一个用于用户,一个用于 Post,一个用于 Meta)。我们的User 和Post 模型都将使用相同的函数来关联我们的Meta 模型:

    User.php
    ========================================
    
    class User extends Eloquent {
        public function meta()
        {
            return $this->morphMany('Meta', 'metable');
        }
    }
    
    
    Post.php
    ========================================
    
    class Post extends Eloquent {
        public function meta()
        {
            return $this->morphMany('Meta', 'metable');
        }
    }
    

    现在我们在元模型中定义这些关系的逆:

    Meta.php
    ========================================
    
    class Meta extends Eloquent {
        public function metable()
        {
            return $this->morphTo();
        }
    }
    

    就是这样!


    获取数据

    现在您需要做的就是获取用户或帖子的元数据:

    // Load in a post with an id of 1 and get all it's related meta
    $post = Post::find(1);
    $meta = $post->meta;
    

    如果我们要返回元对象,我们可能会看到如下内容:

    [{"id":2,"metable_id":1,"metable_type":"Post","name":"author","value":"Steve O"}]
    


    以后!

    您可以从这里创建类似这样的辅助函数,用于检查您所追求的元数据是否存在于结果中:

    public function hasMeta($key)
    {
        $meta = $this->meta;
    
        foreach ($meta as $item):
            if( $item->name == $key ) return true;
        endforeach;
    
        return false;
    }
    
    // Use it like:
    if($post->hasMeta('author')){
        // Display author
    }
    


    在此处的文档中阅读有关 Laravel Eloquent 关系的更多信息:http://laravel.com/docs/eloquent-relationships

    【讨论】:

    • 谢谢,我会在第二天试试这个并更新你。
    • 我认为这是一种简单直接的方式。我期待一点先进的方式。当我检查一些 wordpress 插件时,它会将与实体相关的整个数据存储在像 a:3:{s:9:"firstname";s:10:"irshad.far";s:8:"lastname";s:0:"";s:5:"_meta";a:7:{s:2:"ip";s:10:"14.99.80.3";s:9:"confirmip";s:10:"14.99.80.3";s:11:"confirmtime";d:1407932201;s:8:"signupip";s:10:"14.99.80.3";s:10:"signuptime";d:1407932201;s:4:"lang";s:2:"en";s:4:"form";s:7:"unknown";}} 这样的单行中。他们还从这个对象中提取每个项目,如 firstname 和 lastname。
    • 是的,这确实是您的元设置的基础。您可以使用存储在元表中的数据变得尽可能复杂。您可能想在value 字段中添加json_encode() 一堆变量,例如wordpress 设置。还值得注意的是,示例中的所有元数据都附加到其相关的post/user 对象,因此您仍然可以非常轻松地获得主要值。
    • 我们如何处理包含上述一堆数据的对象中的搜索?
    • 您很可能希望对您的数据库执行自定义查询。您可以遍历结果集,但如果您有一个包含大量元数据的大型集,这会给您带来性能问题。最佳结果将来自优化的自定义数据库查询。
    【解决方案2】:

    我曾经做过类似的事情,我的方法是构建一个迷你数据库引擎,其中表单就像表格,数据就像行:

    描述表单结构和设计的表单:

    Form {
        id,
        title,
        layout,
        ...
    }
    

    具有类型和验证规则的表单字段

    Field {
        formId,
        name,
        type (String, Date, Image, Integer, Double, List, ...),
        pattern (Regex validation maybe),
        ...
    }
    

    表单中插入的数据是属于该表单的一行

    Row {
        id,
        formId,
    }
    

    每一行都是对应表单字段的一组条目,可以按照预定义的规则进行验证。

    Entry {
        rowId,
        fieldId,
        value
    }
    
    • 类型和规则可以在另一个对象中重新组合,这样您就可以拥有可以管理的动态类型。
    • 列表可以有另一个对象来存储列表的选项和类型(多选、单选)

    【讨论】:

      【解决方案3】:

      元数据对象本身将保存在一个表中。但在性能方面,我认为这些对象应该有自己的数据表。

      方法 1)

      这些类型的表单需要预先定义并链接到特定的控制器。这必须是任何一种,以便每种类型的表单(如注册)只有一个控制器,并且在任何时候都只能使用一个用户定义的元数据对象。该控制器的表参数将设置为指向专门为该元数据对象创建的数据库表(或者可能根据元数据迁移同一个表,但该表应该为空)。

      或者 2) 每个元数据对象都应该创建自己的控制器,该控制器指向对象的数据表。

      在每种方法中,需要创建路线以在每次使用时指向每种类型的一个控制器。

      一个难题是如何管理这些对象的修订。也许每个对象都可能有一个流水号后缀,并创建了自己的控制器和数据表(然后迁移甚至填充的表可能会更容易[然后如果用户的操作会导致数据丢失,则会在前端通知用户,例如例如删除表单数据字段])。

      该项目的另一部分是创建一个智能生成器引擎,用于根据元数据对象组装 HTML、CSS 和 JS 代码。生成的代码可以保存在与对象本身相同的表中,并且在使用时应缓存在后端以呈现视图。

      此类元数据对象本身必须具有巧妙的格式,以便它由预定义的设置组成,这些设置将由表单生成器代码转换为功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        • 2017-05-16
        • 2015-09-30
        相关资源
        最近更新 更多