Querying Relations Laravel Eloquent ORM

2019-09-08 05:04发布

问题:

I have an issue understanding pretty well the Relationships, let's go to the point

I have 3 tables, with its proper models

receipt
 - id
 - date

items_sold
 - id
 - receipt_id
 - item_id

items
 - id
 - name

The problem I have is that receipt "has many" items through items_sold, but I can't use "hasManyThrough" because eloquent use the wrong "id" of "items_sold", even if I put manually the keys

class Receipt extends Eloquent {

    public function items()
    {
        return $this->hasManyThrough('Items', 'ItemsSold', 'receipt_id', 'id');
    }

}

There is no way to do it in through this way, but I can find an Relationship method with eloquent that can help me with this case

回答1:

As lukasgeiter stated, a belongsToMany() relationship added to your models would allow you to access the related data.

Something else to note, if you change your join table's name to item_reciept you can define the many to many relationship in your models without having to specify the join table specifically. When Laravel sees a belongsToMany method without a join table name specified, it looks for the name of the two models involved in snake case and alphabetical order with lower case names.

Your model methods would be:

class Receipt extends Eloquent{

    public function items(){
        return $this->belongsToMany('Item');
    }
}

class Item extends Eloquent{

    public function reciepts(){
        return $this->belongsToMany('Reciept');
    }
}

I can understand if you wouldn't want to rename your items_sold table because it's specific name denotes it's usage past just a join table.

Another thing to note about adding these relationships to the model is that it allows your to perform eager loading with your requests which could be helpful in your situations.

Let's say you wanted to get all items for a specific receipt by it's id all in one go. You could use the following request to get everything together:

$receiptAndItems = Receipt::with('items')->find($recieptId);

This would return both the details on your particular Receipt record AND a key items with all of the related Item records for that given receipt:

// Your `receipt` record
// this is the output when you add `->toArray()` at the end to make it a bit easier to read

array (size=7)
  'id' => int 2
  'name' => string 'Foo' (length=12)
  'created_at' => string '2014-11-22 16:30:02' (length=19)
  'updated_at' => string '2014-11-22 16:30:02' (length=19)
  'items' => 
    array (size=3)
      0 => 
        array (size=7)
          'id' => int 1
          'name' => string 'Bar' (length=13)
          'created_at' => string '2014-11-22 16:30:02' (length=19)
          'updated_at' => string '2014-11-22 16:30:02' (length=19)
          'pivot' => 
            array (size=2)
              ...
      1 => 
        array (size=7)
          'id' => int 2
          'name' => string 'Baz' (length=20)
          'created_at' => string '2014-11-22 16:30:02' (length=19)
          'updated_at' => string '2014-11-22 16:30:02' (length=19)
          'pivot' => 
            array (size=2)
              ...
      2 => 
        array (size=7)
          'id' => int 3
          'name' => string 'FooBarBaz' (length=18)
          'created_at' => string '2014-11-22 16:30:02' (length=19)
          'updated_at' => string '2014-11-22 16:30:02' (length=19)
          'pivot' => 
            array (size=2)


回答2:

I'm pretty sure what you actually need is a many-to-many relationship found here

public function items(){
    return $this->belongsToMany('Items', 'items_sold');
}

Is you model really called "Items"? If it's actually "Item", change to first parameter in the above code accordingly