belongsTo关系不能正常工作?

时间:2017-02-15 15:34:10

标签: laravel laravel-5.4

我的模特中有这种关系:

class Product extends Model
{
    protected $fillable = [
        'id', 'title', 'description', 'main_image', 'price', 'category_id', 'in_stock', 'ammount', 'status', 'quatable', 'images'
    ];

    public function enabled_category()
    {
        return $this->belongsTo('App\Categories', 'category_id')->where('enabled', 'yes');
    }

}

我正在尝试获取属于已启用类别的产品,其中enabled == yes

所以我这样得到他们:

$products = Product::with('enabled_category')->get();

但我仍然会获得具有禁用类别的产品,其中categories.enabled =='no'

在我的phpdebugbar中,我只看到这两个查询被调用:

select * from `products`


select * from `categories` where `enabled` = 'yes' and `categories`.`id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49')

我仍然可以获得所有产品,即使是那些禁用类别的产品。

为什么会发生这种情况以及如何获得仅属于已启用类别的产品?

2 个答案:

答案 0 :(得分:1)

这正是你要求的......

$products = Product::with('enabled_category')->get();

您基本上是在告诉Eloquent,为这些产品提取所有产品并急切加载enabled_category关系。因此它将加载所有产品

select * from `products`

然后急切加载这些产品的关系(列表中是加载关系的产品ID,注意你的where子句包含在那里,所以没有急切加载enabled = no,因为它应该......那里很好的优化,只有2个查询...)

select * from `categories` where `enabled` = 'yes' and `categories`.`id` in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49')

@NetGuy建议轻松颠倒查询......这正是您所寻找的。

Category::where("enabled", "yes")->with("products")->get();

您只需在类别中定义产品关系......

希望这有帮助

答案 1 :(得分:1)

根据Eloquent: Relationships中的文档,您尝试直接在动态属性中查询结果。试着这样做:

在您的模型中

public function enabled_category() {return $this->belongsTo('App\Categories', 'category_id'); }

然后在你的控制器中

类别::其中("启用","是") - > with(" products") - > get();

它应该有用!