Latest

Monday, July 10, 2017

Laravel Relationship query

Asked by: Mr Robot


I have 2 models OrderDetails and Product

//OrderDetail MOdel 

    class OrderDetail extends Model
    {
        protected $fillable = ['order_id', 'product_id', 'quantity'];

        protected $hidden = ['created_at','updated_at','deleted_at'];

        public function product() 
        {
            return $this->hasMany('App\Product', 'id');
        }
    }

 //OrderDetails Migration

    Schema::create('order_details', function (Blueprint $table) {
        $table->increments('id');
        $table->string('order_id');
        $table->string('product_id');
        $table->integer('quantity');
        $table->timestamps();
    });

//Products Model

    class Product extends Model
    {
        use SoftDeletes;

        protected $fillable = ['name'];

        protected $hidden = ['created_at','updated_at','deleted_at'];

        protected $dates = ['deleted_at'];

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

        public function orderDetail()
        {
            return $this->belongsTo('App\OrderDetail');
        }
    }

//products migration
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('proportion');
        $table->string('mrp');
        $table->string('price');
        $table->string('category_id');
        $table->string('description')->nullable();
        $table->string('image_small')->nullable();
        $table->string('image_zoom')->nullable();
        $table->enum('trending', ['yes','no']);
        $table->enum('status', ['available','unavailable']);
        $table->timestamps();
        $table->softDeletes();
    });

When user passes Order_id i have to provide order details(products and quantity) of the order, in my controller my able to return the order_details with products using relationship

        public function getDbOrderDetails($order_id)
        {
            $get_orders_details = OrderDetail::where('order_id', $order_id)
                                             ->with('product')
                                             ->get(); 

            $data = [
                'data' => $get_orders_details
            ];

            return Response::json(
                $data_with_status = array_merge($this->respondSuccess('query successfull'), $data)
            );
        }

    //response
{
    "status_code": 200,
    "status_message": "query successfull",
    "data": [
        {
            "id": 1,
            "name": "Chicken Leg Piece",
            "proportion": "1 kg",
            "mrp": "200",
            "price": "185",
            "category_id": "2",
            "description": "Description about the product",
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg",
            "trending": "no",
            "status": "available"
        },
        2,  //should be inside the above object
        {
            "id": 2,
            "name": "Chicken Leg Piece",
            "proportion": "2 kg",
            "mrp": "425",
            "price": "400",
            "category_id": "1",
            "description": "Description about the product",
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg",
            "trending": "yes",
            "status": "available"
        },
        3  //should be inside the above object
    ]
}

The Problem is with the response i'm getting, it is difficult to parse the json at front end app so i wanted the response as below

{
    "status_code": 200,
    "status_message": "query successfull",
    "data": [
        {
            "id": 1,
            "name": "Chicken Leg Piece",
            "proportion": "1 kg",
            "mrp": "200",
            "price": "185",
            "category_id": "2",
            "description": "Description about the product",
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg",
            "trending": "no",
            "status": "available",
            "quantity": 2,            //from order details table
        },
        {
            "id": 2,
            "name": "Chicken Leg Piece",
            "proportion": "2 kg",
            "mrp": "425",
            "price": "400",
            "category_id": "1",
            "description": "Description about the product",
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg",
            "trending": "yes",
            "status": "available",
            "quantity": 4,           //from order details table
        }
    ]
}

is there a way i can get the above response using query

thank you


Answers

Answered by: xmhafiz at 2017-07-11 11:48AM



Use map and flatten from collection will do.

$mapped = $get_orders_details->map(function($v) {
    $v->product->quantity = $v->quantity;

    return $v->product;
})
->flatten()
->all();

$data = [
    'data' => $mapped
];


Answered by: Mr Robot at 2017-07-11 12:37PM



This query gives exactly what i need

public function getDbOrderDetails($order_id)
{
    $get_orders_details = OrderDetail::join('products', 'products.id', '=', 'order_details.product_id')
        ->where('order_id', $order_id)
        ->select('name', 'proportion', 'mrp', 'price', 'quantity', 'image_small', 'image_zoom')
        ->get();
    $data = [
        'data' => $get_orders_details,
    ];

    return Response::json(
        $data_with_status = array_merge($this->respondSuccess('query successfull'), $data)
    );
}

//response
{
    "status_code": 200,
    "status_message": "query successfull",
    "data": [
        {
            "name": "Chicken Leg Piece",
            "proportion": "1 kg",
            "mrp": "200",
            "price": "185",
            "quantity": 2,
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg"
        },
        {
            "name": "Chicken Leg Piece",
            "proportion": "2 kg",
            "mrp": "425",
            "price": "400",
            "quantity": 3,
            "image_small": "Sign.jpg",
            "image_zoom": "Sign.jpg"
        }
    ]
}



Source

No comments:

Post a Comment

Adbox