【问题标题】:Proper way to handle pivot data operations (via has_many "through")处理数据透视数据操作的正确方法(通过 has_many "through")
【发布时间】:2012-05-14 03:49:32
【问题描述】:

在一个基本的博客应用程序中,我有一个文章模块,它允许我选择相关类别。 有3张桌子;文章,article_categories,类别。 2 个模型,Model_Article 和 Model_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);
    }

【问题讨论】:

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


    【解决方案1】:

    您可能应该将关系表重命名为 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']);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 2017-12-09
      • 2010-09-20
      相关资源
      最近更新 更多