MVC设计惯例:CRUDing继承的模型 [英] MVC design convention: CRUDing inherited models

查看:194
本文介绍了MVC设计惯例:CRUDing继承的模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的数据库结构:

在我的应用程序中,我有一个公司管理客户,员工和分支机构。

In my app I have a company management of customers, employees and branches.

客户和员工与一个人,一个人和一个用户。
分支与一个人和一个公司相关联。

Customers and Employees are associated with one Person, one Individual and one User. Branches are associated with one Person and one Company.

所以,要插入一个新的客户或员工,我必须首先将其公共数据插入 Person 表,其人员数据进入 Person 表,然后其用户数据进入用户表,最后在客户 Employee 表中创建一个新记录。

So, to insert a new costumer or employee, I have to first insert its common data into Person table, its person data into Person table, then its user data into User table and finally create a new record into Customer or Employee table.

要插入新的分支,我必须首先将其公共数据插入到 Person 表中,然后将其公司数据插入公司表,最后在分支表中创建一个新记录。

To insert a new branch, I've to first insert its common data into Person table, then its company data into Company table and finally create a new record into Branch table.

我是新的MVC概念,我有点迷失在我应该如何设计我的模型类到CRUD他们。我使用CodeIgniter框架,但我认为这在这里是无关紧要的。我应该为每个数据库表创建一个单独的类模型吗?如果是这样,我应该如何编写代码? (仅理论)

I'm new to MVC concept and I'm a bit lost in how I should design my model classes to CRUD them. I'm using CodeIgniter framework, but I think it's irrelevant here. Should I create a separate class model for each database table? If so, how I should code that? (theory only)

例如,要插入一个新的costumer ...

For example, to insert a new costumer...


  1. 开始一个新的交易

  2. 实例化一个新人

  3. 填写个人资料

  4. li>
  5. 实例化新的个人

  6. 填写个人的数据并与其相关。

  7. 个人保存

  8. 实例化新用户

  9. 填写用户数据并与其相关联

  10. 保存用户

  11. 实例化新的Costumer

  12. 填写Costumer的数据并与其相关。

  13. 保存Costumer

  14. 结束交易

  1. Start a new transaction
  2. Instantiate a new Person
  3. Fill Person's data
  4. Save Person
  5. Instantiate a new Individual
  6. Fill Individual's data and relate to its Person
  7. Save Individual
  8. Instantiate a new User
  9. Fill Users' data and relate to its Person
  10. Save User
  11. Instantiate a new Costumer
  12. Fill Costumer's data and relate to its Person
  13. Save Costumer
  14. End transaction

是否正确?这个代码应该在客户控制器中?使用该数据库结构的任何更好的约定(我需要使用第三个正常表单设计)?

Is that correct? Where this code should be, in the costumer's controller? Any better convention to use that database structure (I need to use the third normal form design)?

推荐答案

好的,有趣的是,为什么要使用3NF?

Ok, interesting, why do you want to use 3NF?

在MVC Web框架(如Codeigniter,Zend Framework或Ruby on Rails)中,您不需要3NF,甚至不需要关心不同的表。我想说的是,多个表继承,这不是很常见。

In MVC web frameworks (like Codeigniter, Zend Framework or Ruby on Rails) you don't require 3NF or even care about the different tables. What you're trying, I'd say, is multiple table inheritance, which is not very common.

所以,实际上你有一个,例如 Custumer 类,它具有您拥有您的Customer,User和Person表的所有属性。要遵守MVC和薄控制器的方法,您将在 CustomerController 保存操作$ c> class接受这些属性,并从这个 Costumer 类中实例化一个对象:

So actually you have a, say, Custumer class, which has all the attributes you have your Customer, User and Person table. To stick to MVC and the thin controller approach, you'd have a save action in your CustomerController class which accepts these attributes and instantiates an object from this Costumer class:

class CostumerController {
    function create() {
        Costumer c = new Customer();
        c.save($_POST['costumer']);
    }
}

(确保您检查SQL注入的参数但是您的框架应该以某种方式处理。)

(Make sure, you check the parameters for SQL injections but your framework should handle that somehow.)

您的customor类应该有一个构造函数,它应该接受所有的属性并将它们保存到相应的表中。即:

Your customor class should have a constructor which should accept all its attributes and save them to the appropriate tables. I.e.:

class Costumer {
    function save(params) {
        $sql = 'INSERT INTO person SET `phoneNumber` = "' . params['phonenumber'] . '"';
        $dbh->query($sql);
        $lastid = PDO::lastInsertId;
        $sql = 'INSERT INTO user SET `password` = "'. md5(params['password']) . '", `personId` = "' . $lastid . '";
        ...
    }
}

注意到,我已经缩短了Sql语句和一些代码,因为我不知道CodeIgniter。但是想法是将所需的所有数据提供给保存方法,将其保存到数据库中的相应表中。记住:只有模型类与MVC中的数据库通信。

As you may have noticed, I've shortened the Sql statements and some of the code since I don't know CodeIgniter. But the idea is to give all the data you need to the save method which saves it to the appropriate tables in you database. Remember: Only the model class communicate with the database in MVC.

问题是您用作外键的ID在其他表。所以在把你的数据插入人之后,你需要查询表中刚刚插入的ID,并在另一个表中使用它。

The problem is the ID you use as a foreign key in other tables. So after inserting your data to person you need to query the table for the ID it just inserted and use it in another table.

这就是为什么一些框架:所有我知道的),默认使用单表继承。图片如下:

That is why some frameworks (so to say: all I know), use single table inheritance by default. Picture it like this:

您描述的方式,您的 Costumer 继承自用户继承自 Person 。所有这些表都合并到一个表中,它还包含一个类型属性,它表示该行对象的类型,在我们的例子中: Customer 用户 Person 。如果只添加一个用户,所有未使用的属性将被设置为 NULL 。但是这样做会打破你的3NF。

The way you described it, your Costumer inherits from User which inherits from Person. All these tables are merged into one table, which also holds a type attribute, which says which type that row's object is, in our case: Customer, User or Person. If you only add a user, all unused attributes will be set to NULL. But this would break your 3NF, of course.

然而,我不明白是为什么你总是需要1:1的关系。例如在 Person 公司之间。
哦,现在我得到它,因为在 Person 中没有 companyId(FK) code>人可以在一个公司中。但是为什么 Branch 有一个 personId(FK)。通常有更多的人在分支机构工作,否?

What I don't understand, though, is why you always require 1:1 relationshipts. For example between Person and Company. Oh, now I get it, since there is no companyId (FK) in Person, many Persons can be in one Company. But why does Branchhave a personId (FK). Usually there are more person working in a branch, no?

回到你的问题

尽管我更喜欢第一个,您可以使用瘦身控制器胖模型 fat-controller-thin-model 。在这种情况下,您的控制器中只有几行,并且您的模型中有更多的逻辑(如上例所示)。与数据库的通信仅在您的模型类中发生。
你通常没有一个一等于一模型的方法,但你也可以有多个模型类型访问一个表(请参阅单表继承的东西)。

You can either use thin-controller-fat-model or fat-controller-thin-model, though I prefer the first one. In this, you'd only have a few lines in your controller and more logic in your model (as in my example above). The communication with the database happens only in your model classes. You usually don't have a one-table-equals-one-model-type approach, but you may also have more than one model type accessing one table (see the single table inheritance thing).

另一种方法

您可以有一个 Costumer 模型接受您的数据,并以表格分散的方式分组:

Your could have a Costumermodel that accepts your data and "group" it the way your tables are "scattered":

class Customer {
    function save(params) {
        Person $person = new Person();
        $person.save(params['person']);
        User $user = new User();
        $user.save(params['user'], $person->id);
        ....
    }
}

但是好吧,正如我所说,我建议你离开3NF方法并使用STI(单表继承)。

But... well, as I said, I'd suggest you leave the 3NF approach and use STI (single table inheritance).

不要忘记确保引用表单数据,以避免SQL注入或查看您的框架为您提供哪些功能。

Don't forget to make sure to quote form data to avoid SQL injections or see, which functions your framework offers to do that for you.

对于代码中的任何错误,我很抱歉只是从内存中编码,甚至没有语法解析它。

Sorry for any mistakes in the code, I was only "coding" from memory and didn't even syntax parse it.

HTH

这篇关于MVC设计惯例:CRUDing继承的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆