在Joomla组件中写入多个表格?

11

我正在尝试创建一个组件(前端),它使用多个表格。我找到了一两篇文章部分回答了这个问题,但没有真正回答完整。对于知道如何做的人来说,这个问题似乎总是简单和明显的,但从未真正解释过(或者我错过了正确的帖子)。

在我的组件中,用户在一个视图中输入数据,需要将其存储在两个表中:

  • 标准Joomla用户表,即#__users
  • 另一个表存储未包含在Joomla中的数据,即#__users_complements

我是初学者,所以也许我错了,但我理解Joomla的标准函数只能将表单结果保存在一个表中。 在我的情况下,我想我必须在我的模型中覆盖标准函数:com_component/model/my_model.php。

1)我感到困惑,因为我并不真正理解应该覆盖哪个函数:save()?store()?还是其他的?

2)假设我重写了save()函数,我是否应重新编写所有保存数据的代码(拆分数据数组并创建所有更新查询),还是应创建2个标准表对象?

在这种情况下(2个对象),每次都向父函数发送整个数据数组似乎很奇怪,因为我知道其中一部分是用于表1,另一部分是用于表2。我应该在之前拆分吗?

3)我应该创建2个模型,并从我的控制器中管理这些模型,当我从表单获取数据并调用模型的保存函数时?

您能帮我澄清如何在多个表中进行保存吗? 附带有代码的示例将非常感谢。 谢谢。

2个回答

20

我终于成功了。由于我花了很多时间,并发现很多人在寻找答案,所以这里是我的解决方法。

我假设您知道如何使用标准MVC结构创建组件:

  1. 组件入口点
  2. 组件控制器
  3. 可能需要的组件路由器
  4. 组件视图
  5. 组件模型
  6. 组件控制器

在模型components\my_component\models\my_model.php中创建自己的保存函数。

public function save($data)
{
    // Initialise variables.
    $userId = (!empty($data['id'])) ? $data['id'] : (int)$this->getState('user.id');
    $user = JFactory::getUser();

    $table_one = $this->getTable('TableOne', 'MyComponentTable', array());
    $table_two = $this->getTable('TableTwo', 'MyComponentTable', array());

    // Bind the data.
    if (!$table_one->bind($data))
    {
        $this->setError(JText::sprintf('USERS PROFILE BIND FAILED', $user->getError()));
        return false;
    }

    if (!$table_two->bind($data))
    {
        $this->setError(JText::sprintf('USERS PROFILE BIND FAILED', $user->getError()));
        return false;
    }

    // Store the data.
    if (!$table_one->save($data))
    {
        $this->setError($user->getError());
        return false;
    }

    if (!$table_two->save($data))
    {
        $this->setError($user->getError());
        return false;
    }

    return $user->id;
}

当然,在save函数中需要调用getTable函数

public function getTable($type = 'TableOne', $prefix = 'MyComponentTable', $config = array())
{
    // call the administrator\components\com_mycomponent\tables\__tablename__.php
    $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables');
    return JTable::getInstance($type, $prefix, $config);
}

并且它起作用了!如此简单! 当然,正如我在问题中所说的那样,整个 $data 被发送到父 save() 函数与不必要的数据,这些数据对 table_one 或 table_two 不重要。 这是在标准 Joomla 结构下工作的方式(没有在代码中进行任何黑客或直接查询)。

希望能有所帮助。


不错。这样做的好处是在保存任何内容之前可以检查是否可以绑定到两个表。 - David Fritsch
2
在Joomla 3中,JTable的保存方法内部使用bind($data),因此在使用保存方法之前不需要绑定数据。 - 3ehrang
由于某种奇怪的原因,这段完全相同的代码无法保存到我的数据库中。你有任何想法吗? - Kuubs

2

也许有些人不同意以下方法稍微破坏了MVC结构,但我发现这对我来说是最简单的。

通常情况下,您会有一个与表格之一匹配的模型。在您将数据推送到用户表以及组件中的一个示例中,我会在组件中表的模型中添加以下内容:

public function save($data) {
    if (!parent::save($data)) {
        return false;
    }

    // add necessary code to save to the users table, since there isn't a standard way to do this that I'm aware of

    // sometimes I will grab another model even
    require_once(JPATH_BASE . '/administrator/components/com_users/models/user.php');
    $other_model = $this->getInstance('user', 'UsersModel');
    $other_model->save($data);

    return true;
}

这个函数的第一部分应该像平常一样将数据保存到组件表中。但你可以在其余部分上添加你需要的内容,以实现你想要的任何操作。
我几乎可以保证,有更好的方法来链接模型(我已经看到了 Joomla 平台核心正在发生的一些变化,这将导致未来有更好的方法),但是现在这种方法应该能够使你开始。
此外,在第三个提示中,如果您需要有时只保存一个表格,有时保存两个表格,我会在控制器中处理。我发现即使有些部分没有加载,保存函数也很安全运行,所以我通常让它运行。

谢谢David,我更喜欢另一种方法(请看我的答案)。 - l_r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接