使用Yii的MySQL中的外键

时间:2012-02-13 16:45:06

标签: mysql yii relational-database

我有这样的数据库

==== Invoices ====
id
costumer_id
description

==== Costumers ===
id
firstname
lastname

现在我已经在模型之间建立了关系。在Invoices模型中,关系就像这样

 public function relations()
  {
    return array(
    'customer' => array(self::BELONGS_TO, 'Customer', 'customer_id')
    );
  }

在costumer模型中,关系就像这样

  public function relations()
  {
    return array(
      'invoice' => array(self::HAS_MANY, 'Invoices','customer_id')
    );
  }

现在,我的关系被定义为一个客户有很多发票,发票属于客户。   现在我制作了多模型并将Costumer模型加载到Invoice模型中。就像这样。

  public function actionCreate()
  {
    $model = new Invoices;
    $customers = new Customers;
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($model);

    if (isset($_POST['Invoices'],$_POST['Customers']))
    {
      $model->attributes = $_POST['Invoices'];
      $customers->attributes = $_POST['Customers'];
      $valid = $model->validate();
      $valid = $customers->validate();
      if($valid)
      {
        $model->save(false);
        $customers->id = $model->customer_id;
        $customers->save(false);
        $this->redirect(array('view','id'=>$model->id));
      }
    }

    $this->render('create',array(
      'model'=>$model,
      'customers'=>$customers,
    ));
  }

这里的每件事都没问题。我可以轻松插入两个模型的数据。但我的问题来自于当我从Invoice多模型插入数据时,外键ID没有改变。它每次都显示为零。有人可以告诉我哪里错了。任何帮助和建议都会非常适合。

2 个答案:

答案 0 :(得分:2)

我的猜测是你用发票的外键覆盖客户的主键。我不是说那种方式不正确(也许在你的场景中它是有道理的)。

让我解释一下你在该代码中所做的事情:

  • 首先,您创建两个模型的新实例,即发票和客户。 Yii理解为“他们希望在数据库中插入新项目”。

  • 然后,检查是否有来自ajax表单的项目。如果是,那么,

  • 您填写发票(定义为$model。我会将其更改为$invoice,以防您需要进一步修改和理解。
  • 您还会弹出客户的信息,覆盖$valid值(因此,您不知道发票是否真的有效)。
  • 如果有效(请记住您只是验证客户的信息),请执行
  • 保存发票
  • 使用发票的销售密钥覆盖客户的ID。
  • 保存客户并重定向。

现在,我从那里得到了什么:

  • $valid无法正常工作:我将其更改为增量分配。
  • 您可能无法传递来自ajax表单的customer_id。外键是整数,因此如果未在模型中定义,则变为0或NULL
  • 您总是将id = 0 / NULL传递给客户的模型,因此在验证时可能会发出警告。但是,您正在使用save(false),这意味着它不会在保存时进行预验证,因此您永远不会知道它不起作用。

所以,根据这个:

  public function actionCreate()
  {
    $invoice = new Invoices;
    $customers = new Customers;
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($invoice);

    if (isset($_POST['Invoices'],$_POST['Customers']))
    {
      $invoice->attributes = $_POST['Invoices'];
      $customers->attributes = $_POST['Customers'];
      $valid = true; /* expect it is always valid */
      $valid &= $invoice->validate(); /* if $invoice is not valid, $valid will be false (true&false = false) */
      $valid &= $customers->validate(); /* same as the above line */
      if($valid)
      {
        $customers->save(); /* First save customers. It's the Foreign item */
        $invoice->customer_id = $customers->getPrimaryKey(); /* new instances use getPrimaryKey() to get its id */
        $invoice->save(); /* Save invoice AFTER getting customer's primary key */
        $this->redirect(array('view','id'=>$invoice->id));
      }
    }

    $this->render('create',array(
      'invoice'=>$invoice,
      'customers'=>$customers,
    ));
  }

我希望这能解决你的问题。

答案 1 :(得分:0)

请你在这里了解一个清晰的场景。你为什么要用 如果($有效)       {         $模型 - >保存(假);         $ customers-> id = $ model-> customer_id;         $客户 - >保存(假);         $这 - >重定向(阵列( '观看', 'ID'=> $模型 - > ID));       }

$模型 - >保存(假);告诉模型,如果这条记录不是save(),它应该设置$ customers-> id = $ model-> customer_id;

这只会返回false,因为。如果您在$ model-> save();

之前致电($ customers-> id = $ model-> customer_id;),我更愿意

请记住,如果您需要检查Save()是否返回true,则将其设置为$ model-> save(true)