Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 四对多关系,有口才_Php_Laravel_Laravel 4_Relationship_Eloquent - Fatal编程技术网

Php 四对多关系,有口才

Php 四对多关系,有口才,php,laravel,laravel-4,relationship,eloquent,Php,Laravel,Laravel 4,Relationship,Eloquent,我正在使用Laravels雄辩的ORM,我遇到了一个特殊关系的小问题。假设我有下表: Recipe: id | ... | ingredient1 | ingredient2 | ingredient3 | ingredient4 每个配方都有4种配料,我从外部来源以这种特定格式获取数据,这就是为什么我将配料作为列,而不是正常的多对多关系 我可以将这些设置为4个一对多关系,但我希望能够编写$component->usedincipes()->get() 对于4个一对多关系,我必须编写$c

我正在使用Laravels雄辩的ORM,我遇到了一个特殊关系的小问题。假设我有下表:

Recipe:
   id | ... | ingredient1 | ingredient2 | ingredient3 | ingredient4
每个配方都有4种配料,我从外部来源以这种特定格式获取数据,这就是为什么我将配料作为列,而不是正常的多对多关系

我可以将这些设置为4个一对多关系,但我希望能够编写
$component->usedincipes()->get()

对于4个一对多关系,我必须编写
$component->usedincipesasingredient1()->get()
,[…],
$component->usedincipesasingredient4()->get()
,然后合并它们,这将导致4个查询


如果您知道在查询数据库之前加入这些的好方法,或者知道如何使4对多关系工作,请回答

从这个问题上,我无法判断您是否已经尝试过这样做,尽管在我看来,您只需要使用单个多对多关系

每个成分大概都有一组共同的属性,可以在一个表中处理所有这些属性

id    name        created_at                updated_at
1     Paprika     01/01/1970 00:00:00       01/01/1970 00:00:00
1     Rosemary    01/01/1970 00:00:00       01/01/1970 00:00:00
1     Basil       01/01/1970 00:00:00       01/01/1970 00:00:00
1     Oregano     01/01/1970 00:00:00       01/01/1970 00:00:00
然后是你的
食谱
表格

id    name        created_at                updated_at
1     Herb Soup   01/01/1970 00:00:00       01/01/1970 00:00:00
要保存这些关系,请使用数据透视表
component\u recipe

id    recipe_id   ingredient_id
1     1           1
2     1           2
3     1           3
4     1           4
现在,您所需要的是在您的
配方
配料
模型上建立一个
属于“口香糖”的关系

public function scopeGetWithIngredients($query)
{
    $query->leftJoin('ingredients i1', 'recipes.ingredient_1', '=', 'i1.id')
          ->leftJoin('ingredients i2', 'recipes.ingredient_2', '=', 'i2.id')
          ->leftJoin('ingredients i3', 'recipes.ingredient_3', '=', 'i3.id')
          ->leftJoin('ingredients i4', 'recipes.ingredient_4', '=', 'i4.id')
          ->select('recipes.name', 'i1.name AS ing_1', 'i2.name AS ing_2');
}
您可以编写保护代码,以确保一个配方与配料之间只有4种关系,但前提是要保持简单:

Recipe::with('ingredients')->get();
将检索所有配料以及配方

不带枢轴

如果在
配方
表中保留列
成分_1
成分_2
等,则可以将类似内容添加到
配方
模型中

public function scopeGetWithIngredients($query)
{
    $query->leftJoin('ingredients i1', 'recipes.ingredient_1', '=', 'i1.id')
          ->leftJoin('ingredients i2', 'recipes.ingredient_2', '=', 'i2.id')
          ->leftJoin('ingredients i3', 'recipes.ingredient_3', '=', 'i3.id')
          ->leftJoin('ingredients i4', 'recipes.ingredient_4', '=', 'i4.id')
          ->select('recipes.name', 'i1.name AS ing_1', 'i2.name AS ing_2');
}
然后,你就可以在你的模型中使用

Recipe::getWithIngredients();

我找到了一个似乎在我所有用例中都有效的解决方案

在配方模型中,我将4种成分定义为一对多关系,并创建了两个辅助作用域函数

class Recipe extends Eloquent { 
    public function ingredient1()
        { return $this->belongsTo('Ingredient', 'ingredient1'); }
    public function ingredient2()
        { return $this->belongsTo('Ingredient', 'ingredient2'); }
    public function ingredient3()
        { return $this->belongsTo('Ingredient', 'ingredient3'); }
    public function ingredient4()
        { return $this->belongsTo('Ingredient', 'ingredient4'); }

    public function scopeHasIngredient( $query, Ingredient $ingredient ) {
        return $query->  where( 'ingredient1', '=', $ingredient->id )
                     ->orWhere( 'ingredient2', '=', $ingredient->id )
                     ->orWhere( 'ingredient3', '=', $ingredient->id )
                     ->orWhere( 'ingredient4', '=', $ingredient->id );
    }

    public function scopeWithIngredients( $query ) {
        return $query->with('ingredient1', 'ingredient2',
                            'ingredient3', 'ingredient4');
    }
}

class Ingredient extends Eloquent {
    public function ingredientForRecipes() {
        return Recipe::hasIngredient( $this )->withIngredients();
    }
}

要获取一种配料的所有配方,我现在可以调用
$component->ingredientForRecipes()->get()
,无需额外查询即可使用这些配料。

是的,我可以这样做,但我正在寻找一个没有透视表的解决方案,因为其他一些项目访问相同的数据库。如果没有一个好的解决方案,我将使用透视表并调整其他项目。@darthmaim好的,很公平。我仍然会亲自走这条支点路线,因为它感觉更正常。我说我添加了一种未经测试的方法,你可以在你的模型上使用fluent连接和作用域方法来获取成分。太棒了,我会尝试一下。