处理透视数据操作的正确方法(通过has_many“through”)

时间:2012-05-14 03:49:32

标签: php orm kohana kohana-3 kohana-3.2

在基本的博客应用程序中,我有一个文章模块,允许我选择相关的类别。 共有3张桌子;文章,article_categories,类别。 2个模型,Model_ArticleModel_Category扩展ORM,并相应地指定了多个“通过”关系。在“编辑文章”表单提交期间,正确的方法(或更好的方式)是:

  • 以数组格式检索所有可用的category ids以填充Form::select()
  • 从数据透视表中检索已分配的category ids,以所选类别的数组格式
  • 成功提交表单后更新数据透视表,其中某些数据透视表数据已存在。最好在添加/删除相关数据之前检查现有数据(而不是删除所有现有的数据透视数据,然后添加所有提交的category ids)。

基本上我希望有一种方法可以在不绕过ORM对象的情况下获取数据透视数据数组。

不确定我要求的是否只能通过数据库预处理语句/查询构建器完成。如果是这样,我建议将自己的方法(使用预先准备的语句/查询构建器)添加到我的Model_Article extend ORM吗?

我正在使用的当前方法是:

获取所有类别ID

    $categories_orm = ORM::factory('article_category')->find_all();
    foreach($categories_orm as $category_orm) {
        $categories[$category_orm->id] = $category_orm->name;
    }

获取所选类别ID

    $categories_current = $article->article_categories->find_all();
    foreach($categories_current as $category){
        $categories_selected = $category->id;
    }

更新类别ID

    $categories_orm = $article->article_categories->find_all();
    $categories_existing = array();
    foreach($categories_orm as $category){
        $categories_existing[] = $category->id;
    }
    $categories_selected = $this->request->post('category');

    $categories_to_remove = array_diff($categories_existing,$categories_selected);
    $categories_to_add = array_diff($categories_selected,$categories_existing);
    if(!empty($categories_to_remove)) {
        $article->remove('article_categories', $categories_to_remove);
    }
    if(!empty($categories_to_add)) {
        $article->add('article_categories', $categories_to_add);
    }

1 个答案:

答案 0 :(得分:0)

您可能应该将关系表重命名为articles_categories(复数形式)以遵循Kohana惯例,而categories是该关系的更好别名。

类别模型应该用于检索所有类别ID。然后循环遍历它,就像填充数组一样。

获取所有类别。

$categories_orm = ORM::factory('category')->find_all();
foreach ($categories_orm as $category)
{
    $categories[$categories_orm->id] = $categories_orm->name;   
}

确保您的select元素通过命名为数组中的post值:

name="categories[]"

更新关系。

$article = ORM::factory('article', $post['article_id']);

// do stuff (validate, update the article etc.)

// remove all relationships
$article->remove('categories');

// add new relationships
$article->add('categories', $post['categories']);

我可能会使用隐藏的表单字段进行检查,以首先验证是否需要更新类别关系。我想象文章的类别很少会改变。