Laravel 中的元数据对象处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25243722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Metadata object handling in Laravel
提问by devo
I need to develop a custom form generator using Laravel.
我需要使用 Laravel 开发自定义表单生成器。
That means there will be a GUI to select and customise the forms like Registration Form
or Booking Form
.User should be able to add/edit/delete different form controls, define it as mandatory, etc.
这意味着将有一个 GUI 来选择和自定义表单,例如Registration Form
或 。Booking Form
用户应该能够添加/编辑/删除不同的表单控件,将其定义为强制性等。
Here I am little confused to handle this in back-end. What is the better way to achieve this?
在这里,我有点困惑在后端处理这个问题。实现这一目标的更好方法是什么?
Or how can I implement a database architecture to use some metadata table which can be used to handle multiple items like Wordpress
and is there any built-in Laravel functionalities to handle these meta objects?
或者我如何实现一个数据库架构来使用一些元数据表来处理多个项目,比如Wordpress
是否有任何内置的 Laravel 功能来处理这些元对象?
And how the insert/update/delete
handled in this metadata approach?
以及如何insert/update/delete
在这种元数据方法中处理?
Here an insert should have only one row in the meta table. Suppose at the time of user registration, without saving the firstname
and lastname
in separate rows in the meta table, it should use some objects like this in a single row.
这里的插入应该在元表中只有一行。假设在用户注册时,没有将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";}}
回答by Steve O
Handling a table of meta data is fairly straight forward using Laravel's Eloquent relations. Let's say you have a users table in your database that contains:
使用 Laravel 的 Eloquent 关系处理元数据表相当简单。假设您的数据库中有一个 users 表,其中包含:
id email password created_at updated_at deleted_at
If you want to keep it simple and not add all sorts of extra data to your users table you could create a meta
table and then a link table user_meta
to relate the two.
如果您想保持简单并且不想将各种额外数据添加到您的用户表中,您可以创建一个meta
表,然后创建一个链接表user_meta
来关联两者。
But what if you also have a posts
table (as with Wordpress) and your posts also need meta data? Instead of also creating a posts_meta
table to link your posts to their meta, we can use Laravels Eloquent relations and create some Polymorphic Relations.
但是,如果您还有一个posts
表格(与 Wordpress 一样)并且您的帖子也需要元数据怎么办?posts_meta
我们可以使用 Laravel Eloquent 关系并创建一些多态关系,而不是创建一个表格来将您的帖子链接到他们的元数据。
The Database
数据库
Here's our setup, along with our users
table (above) we have a posts
table which has the fields:
这是我们的设置,连同我们的users
表(上面),我们有一个posts
包含字段的表:
id title content created_at updated_at deleted_at
We also have our meta
table that follows the guidelines for a polymorphic relation:
我们还有meta
遵循多态关系准则的表格:
id name value metable_id metable_type
//int meta key meta value post/user id resource ie post/user
Using this we could add meta for a post or user to our meta table like this:
使用它,我们可以像这样将帖子或用户的元数据添加到我们的元表中:
id name value metable_id metable_type
------------------------------------------------------
1 nickname Steve 1 User
2 author Steve O 1 Post
All we need to do to grab this info from the database is define the relations in our respective models.
从数据库中获取这些信息所需要做的就是在我们各自的模型中定义关系。
The Models
模型
So now we have our DB ready we need to setup our models (one model for User, one for Post and one for Meta) with our polymorphic relationship. Our User
and Post
models are both going to use the same function to relate to our Meta
model:
所以现在我们已经准备好了我们的数据库,我们需要使用我们的多态关系来设置我们的模型(一个用于 User 的模型,一个用于 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');
}
}
Now we define the inverse of those relations in our meta model:
现在我们在元模型中定义这些关系的逆:
Meta.php
========================================
class Meta extends Eloquent {
public function metable()
{
return $this->morphTo();
}
}
That's it!
就是这样!
Getting the data
获取数据
Now all you need to do to get at the meta data for a user or post is:
现在您需要做的就是获取用户或帖子的元数据:
// Load in a post with an id of 1 and get all it's related meta
$post = Post::find(1);
$meta = $post->meta;
If we were to return the meta object we might see something like:
如果我们要返回元对象,我们可能会看到如下内容:
[{"id":2,"metable_id":1,"metable_type":"Post","name":"author","value":"Steve O"}]
Onwards!
向前!
From here you can create helper functions like this one that checks if the meta you're after exists in the results:
从这里你可以创建这样的辅助函数来检查你所追求的元是否存在于结果中:
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
}
Read more about Laravels Eloquent relationships in the docs here: http://laravel.com/docs/eloquent-relationships
在此处的文档中阅读有关 Laravel Eloquent 关系的更多信息:http://laravel.com/docs/eloquent-relationships
回答by Issam Zoli
I once did something similar, my approach was to build a mini DB engine where forms are like tables and data is rows:
我曾经做过类似的事情,我的方法是构建一个迷你数据库引擎,其中表单就像表,数据是行:
A form which describes the structure and design of a form:
描述表单结构和设计的表单:
Form {
id,
title,
layout,
...
}
Fields of the form with types and validation rules
具有类型和验证规则的表单字段
Field {
formId,
name,
type (String, Date, Image, Integer, Double, List, ...),
pattern (Regex validation maybe),
...
}
Inserted data in a form is a row belonging to that form
表单中插入的数据是属于该表单的一行
Row {
id,
formId,
}
Each row is a group of entries to fields of the corresponding form that can be validated following the predefined rules.
每行是一组对应表单字段的条目,可以按照预定义的规则进行验证。
Entry {
rowId,
fieldId,
value
}
- Type and rules can be regrouped in another object so you can have dynamic types that you can manage.
- Lists can have another object that stores choices and type of list (multi-select, mono-select)
- 类型和规则可以在另一个对象中重新组合,这样您就可以拥有可以管理的动态类型。
- 列表可以有另一个对象来存储选择和列表类型(多选、单选)
回答by ux.engineer
Metadataobjects itself would be saved in one table. But performance-wise I think those object should their own data tables.
元数据对象本身将保存在一张表中。但在性能方面我认为这些对象应该有自己的数据表。
Approach 1)
方法 1)
These types of forms needs to be predefined and linked to a specific controller. This must be either so that there is only one controller for each type of form like Registeration, and only one user defined metadataobject can be in use at either time. This controller's table parameter would be set to point to a database table created specifically for that metadataobject (or perhaps same table could be migrated according to metadata but then that table should be empty).
这些类型的表单需要预定义并链接到特定的控制器。这必须是这样,以便每种类型的表单(如注册)只有一个控制器,并且在任何时候都只能使用一个用户定义的元数据对象。该控制器的表参数将被设置为指向专门为该元数据对象创建的数据库表(或者可能根据元数据迁移同一个表,但该表应该是空的)。
Or 2) every metadataobject should have it's own controller created which points to the object's data table.
或者 2) 每个元数据对象都应该创建自己的控制器,该控制器指向对象的数据表。
In each approach routes needs to be created to point to the one controller of each type at use in each time.
在每种方法中,需要创建路由以指向每次使用的每种类型的一个控制器。
One dilemma is how to manage revisions of those objects. Perhaps each object might have a running number postfix, and have their own controllers and data tables created (then it might be easier to migrate even populated tables [then user would be notified on front-end if his action would result in data loss, like for example with deleting a form data field]).
一个难题是如何管理这些对象的修订。也许每个对象都可能有一个运行编号后缀,并创建了自己的控制器和数据表(然后迁移甚至填充的表可能更容易[然后用户会在前端收到通知,如果他的操作会导致数据丢失,例如例如删除表单数据字段])。
Another part of this project is to create an intelligent generator engine for assembling the HTML, CSS, and JS code according to a metadataobject. The generated code can be saved to reside in the same table as the objects themselves, and when used should be cached in the backend for rendering views.
该项目的另一部分是创建一个智能生成器引擎,用于根据元数据对象组装 HTML、CSS 和 JS 代码。生成的代码可以保存在与对象本身相同的表中,使用时应该缓存在后端以供渲染视图。
Such metadataobject must itself have a clever format, so that it composes of predefined pieces of settings which will be converted to functionality by the form generator code.
此类元数据对象本身必须具有巧妙的格式,以便它由预定义的设置组成,这些设置将通过表单生成器代码转换为功能。