如何在laravel中显示来自不同表格的数据?

Terms table

  • term_id
  • name
  • slug

Term_taxonomy table

  • term_taxonomy_id
  • term_id
  • description

i want to show all record like "term_id , name , description

my Term model

public function TermTaxonomy(){
    return $this->hasOne('TermTaxonomy');
}

my TermTaxonomy model

public function Term(){
    return $this->belongsTo('Term');
}

my route

$term = new Term;
$categories = $term->all(['term_id', 'name']);
foreach($categories as $category){
    echo $category->term_id . " " . $category->name . " " . "description of term_id should here" ;} 

trying this code but Error Undefined property: Illuminate\Database\Eloquent\Collection::$TermTaxonomy

$e = new Term;
$f = $e->all(['term_id','name']);
    echo $f->TermTaxonomy->description;
}

with the above code i want to return all description of each term_id, but i am confusing why i can show description if the object just 1 , like this code below

$a = new Term;
$b = $a->all(['term_id','name'])->find(8);
echo $b->TermTaxonomy->description . "<br>"; // work return description of $b;

so what is exactly one to one relationship function ? is one to one only work when the object just 1 ?

what about in my case ? is my logic wrong to show all description using relationship method ? then what must i do to show term id , name , description lists ?

thanks in advance, i am totally newbie in laravel.

You can't access relationships on collections directly. I mean, what would you even expect? All descriptions as comma separated list?

Instead you just access the relation when you loop over all of them anyways. (That's probably in the view so I'm going to use Blade syntax in this example)

@foreach($terms as $term)
    {{ $term->term_id }} {{ $term->name }} {{ ($term->TermTaxonomy ? $term->TermTaxonomy->description : '') }}
@endforeach

($term->TermTaxonomy ? $term->TermTaxonomy->description : '') is a shorthand if. It means:

if($term->TermTaxonomy){
    echo $term->TermTaxonomy->description;
}
else {
    echo '';
}

It works because if the Term has no TermTaxonomy assigned, $term->TermTaxonomy will be null. With this code we only try to access ->description if TermTaxonomy exists and can therefore avoid a Trying to get property of non-object exception.


Attention: While this works you definitely should eager load the TermTaxonomy relationship. You see if we leave it like that, each time you do $term->TermTaxonomy a DB query will be run. To avoid n+1 queries, use with to eager load relationships:

$terms = Term::with('TermTaxonomy')->get(['term_id','name']);

Regarding your question in the comments, yes you can limit the fields that you select from term_taxonomy:

$terms = Term::with(['TermTaxonomy' => function($q){
    $q->select('term_id', 'description');
}])->get(['term_id','name']);

Just make sure you include the columns necessary to make the relationship (in this case term_id)

If you do a $e-all, you get an array with the TermTaxanomies. When you do a specific search (->find(8)) you only get that object with id = 8.

All you need to do is use a foreach or use an index number:

$f = $e->all(['term_id','name']);
foreach($f as $tax){
    var_dump($tax);
}

Or

$f = $e->all(['term_id','name']);
var_dump($f[1]);
var_dump($f[4]);

I think that should work.

oops! Looks like you're trying to implement raw php code into Laravel. Please get rid of that , follow the instructions bellow.

make a Route:

    Route::get('/term' , array('uses' => 'TermsController@showTerm'));

Now make a Controller named TermsController.php and try something like bellow:

       <?php
          class TermsController extends BaseController {
               public function showTerm(){
                       $terms = Term::all();
              return View::make('show_term.blade.php')->with('terms' , $terms);
           }
       }//class ends

Now make a Model named Term.php :

 <?php
       class Terms extends \Eloquent{
         protected $fillable = array();
         protected $table = 'terms'; //terms is your database table name
   }?>

Now make a show_term.blade.php :

   @extends(layouts.master)
   @section('content)
    foreach($terms as term){
     {{$term->id}} , {{$term->name}} , {{$term->slug}}}
      @stop

if you don't have the layouts.master then create a layouts folder inside you View folder. Then create a master.blade.php write the basic html and inside the body try like this:

  <div class="container"> 
    @yield('content')
   </div>

Thank you . Let me know if you need anything else.