Search code examples
phplaravel-4ionic-frameworksingle-page-applicationhybrid-mobile-app

how to make an api for ionic from two tables(users and posts) in database


I want to make an api (i use laravel 4.2 for backend)for use of the ionic app. for example:

//I made the following $tourists:

                    $tourists = User::where('block','0')
                          ->where('guider', 1)
                           ->where('location', $location)
                           ->orderBy($orderBy, 'desc')
                           ->orderBy('updated_at', 'desc')
                           ->get(); 
                 return View::make('frontend.data.touristsData',array('tourists'=>$tourists)); 

// touristsData :

    <?php
  echo json_encode($tourists);

//used it in my app.js(ionic):

.controller('listController', ['$scope','$http','$state','$ionicModal', function($scope, $http, $state,$ionicModal){

    $http.get("./touristsData").success(

         function(data){
            $scope.tourists = data;
......

//used in the html

<div>{{tourists.username}}: {{tourists.intro}}</div>

//the above is for one table

but what if i have two tables, for example, users table and posts table

//users table (laravel migration)

            $table -> increments('id');//id auto_increment
        $table -> string('username',30);
        $table -> string('email',60) -> unique();
        $table -> string('password',64);
        $table -> boolean('admin')->default(0);
        $table -> boolean('block')->default(0);

        $table -> integer('tradeTime');
        $table -> string('nationality', 50);

//posts table

            $table->increments('id');
        $table -> integer('needHour');


        $table -> string('travelDestination',40);
        $table -> text('intro',300);
        $table -> string('otherWords', 100);
        $table->integer('user_id');
        $table->softDeletes();   

        $table ->timestamps(); 

//user.php

    <?php

use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface {

    use UserTrait, RemindableTrait;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';
       protected $guard = array('email', 'password');

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = array('password', 'remember_token');


    public function posts(){
        return $this->hasMany('Posts');
    }

//post.php

    <?php
use Illuminate\Database\Eloquent\SoftDeletingTrait;
class post extends Eloquent{
   use SoftDeletingTrait;
   protected $dates = ['deleted_at'];

  protected $fillable = ['needHour', 'travelDestination','intro','otherWords'];


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

we can see that the users table and posts table is linked to each other by user_id, so my question is how we can output the contents of the two table combined ,just like the above ,which only has one table to output(that is easy)?

what i want to achevie is like the following code:

<div>{{tourists.username}} : {{tourists.travelDestination}}</div>

Solution

  • There are many ways to achieve this.

    You can use joins

    $userWithDestinations = User::where('condition')->join('destination_table', function ($join)
    {
       $join->on('user.userID', '=', 'post_table.userID')
    })->where('moreConditions')->get()
    

    You can use Laravel Eager Loading (I strongly recommend this approach for reusable purposes)

    Your user model could look like this

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class User extends Model
    {
        /**
         * The table associated with the model.
         *
         * @var string
         */
        protected $table = 'users';
    
        public function posts()
        {
            return $this->hasMany('App\Posts');
        }       
    }
    

    In order to do something like this:

    $userWithDestinations = User::where('condition')->with(['posts'])->where('moreConditions')->get();
    

    This last code using the eager loading will generate a JSON data like this:

    [
        {
            userID:1,
            name: Luis,
            posts:
            [
                {
                    postID: 1,
                    travelDestination: 'Mexico'
                },
                {
                    postID: 11,
                    travelDestination: 'France'
                },              
            ]
        },
        {
            userID:13,
            name: John,
            posts:
            [
                {
                    postID: 14,
                    travelDestination: 'Germany'
                },
                {
                    postID: 55,
                    travelDestination: 'Brazil'
                },              
            ]
        }       
    ]
    

    Since your USER-POSTS is a 1-N relationship, in Angular you could do something like the following code if you want to get only the first post per user.

    {{tourist.username}} : {{tourist.posts[0].travelDestination}}
    

    Larevel Model Docs

    https://laravel.com/docs/5.1/eloquent-relationships

    NOTE

    Your question summary isn't actually about "makie an API", it's more of a Laravel-Model doubt.