Many to Many Ajax Laravel 5.2 - laravel

I have this code.
public function items( $subcategory_id ){
$items = $this->ajax->items( $subcategory_id );
return Response::json([
'success' => 'true',
'items' => $items
]);
}
And the output is:
As you can see the unit_id reference to many to many and you can't manipulate it to get the name of the unit_id in javascript. Do I need to loop it and create my own array or is there a function to do it.
Here is my repository code.
public function items( $subcategory_id ){
$this->modelName = new Subcategory();
return $this->modelName->find( $subcategory_id )->items;
}
My Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Subcategory extends Model
{
protected $table = 'subcategories';
protected $fillable = [
'qty', 'desc', 'unit_price', 'ext_price'
];
public function items(){
return $this->belongsToMany('App\Item', 'item_subcategory', 'subcategory_id', 'item_id')->withTimestamps();
}
}

Use eager loading. This will fetch the a specific Subcategory with its related Items and Units related to those items:
Subcategory::where('id', $subcategoryId)->with('items.unit')->get();

Related

Lavarel & Vue e-commerce: how to post an order as array of products instead of single product

I am kinda new to both Laravel and Vue and I am working on a school project. I have been following a guide and trying to develop the product but I have the following problem: in the guide was only possible to do an order with a single product. Using LocalStorage a created a Cart component where you can add several products instead. How do I use axios.post to correctly post the order in the database now?
app/Http/Controllers/OrderController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Order;
use Auth;
use Illuminate\Http\Request;
class OrderController extends Controller
{
public function index()
{
return response()->json(Order::with(['product'])->get(),200);
}
public function store(Request $request)
{
$order = Order::create([
'product_id' => $request->product_id,
'user_id' => Auth::id(),
'quantity' => $request->quantity,
'address' => $request->address
]);
return response()->json([
'status' => (bool) $order,
'data' => $order,
'message' => $order ? 'Order Created!' : 'Error Creating Order'
]);
}
public function show(Order $order)
{
return response()->json($order,200);
}
Resources/JS/views/Checkout.vue (between < script > tag):
placeOrder(e) {
e.preventDefault()
let address = this.address
let product_id = this.product.id
let quantity = this.quantity
axios.post('api/orders/', {address, quantity, product_id})
.then(response => this.$router.push('/confirmation'))
},
App/Http/Models/Order.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Order extends Model
{
use SoftDeletes;
protected $fillable = [
'product_id', 'user_id', 'quantity', 'address'
];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
}
Actually, You can achieve your goal by changing many lines of code instead of using your current code at backend (laravel Model-Controller) and frontend (Vue). I will show you how to do by adding hasMany relationship in your User model structure, then changing saving method at controller, and axios request payload. This method has limitation, you have to post an array of products of the same user ID.
Add hasMany relationship in your User Model. Read this
class User extends Model
{
//add this line
public function order()
{
return $this->hasMany(Order::class);
}
Use createMany function to save multiple rows in your controller. Read this
public function store(Request $request)
{
//use this lines to store array of orders
$user = Auth::user();
$orderStored = $user->order()->createMany($request->data);
//return your response after this line
}
Change your axios payload from vue method
data(){
return {
//add new key data to store array of order
arrayOfOrders:[];
};
},
methods:{
placeOrder(e) {
e.preventDefault()
let address = this.address
let product_id = this.product.id
let quantity = this.quantity
//remark these lines, change with storing to arrayOfOrders data instead of doing post request
//axios.post('api/orders/', {address, quantity, product_id})
//.then(response => this.$router.push('/confirmation'))
this.arrayOfOrders.push({
product_id:product_id,
quantity:quantity,
address:address
});
},
//create new function to make post request and call it from your button
postData(){
let instance = this;
axios.post('api/orders/', {
data:instance.arrayOfOrders
}).then(response => this.$router.push('/confirmation'))
}
}
Thank you for your answer! Just one thing is not so clear.. in my OrderController.php should the final code look something like this?
public function store(Request $request)
{
$user = Auth::user();
$order = $user->order()->createMany([
'product_id' => $request->product_id,
'user_id' => Auth::id(),
'quantity' => $request->quantity,
'address' => $request->address
]);
return response()->json([
'status' => (bool) $order,``
'data' => $order,
'message' => $order ? 'Order Created!' : 'Error Creating Order'
]);
}

How can I add, delete and get a favorite from product with polymorphic relationship, in Laravel 5.6?

My product model like this :
<?php
...
class Product extends Model
{
...
protected $fillable = ['name','photo','description',...];
public function favorites(){
return $this->morphMany(Favorite::class, 'favoritable');
}
}
My favorite model like this :
<?php
...
class Favorite extends Model
{
...
protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
public function favoritable()
{
return $this->morphTo();
}
}
My eloquent query laravel to add, delete and get like this :
public function addWishlist($product_id)
{
$result = Favorite::create([
'user_id' => auth()->user()->id,
'favoritable_id' => $product_id,
'favoritable_type' => 'App\Models\Product',
'created_at' => Carbon::now()
]);
return $result;
}
public function deleteWishlist($product_id)
{
$result = Favorite::where('user_id', auth()->user()->id)
->where('favoritable_id', $product_id)
->delete();
return $result;
}
public function getWishlist($product_id)
{
$result = Favorite::where('user_id', auth()->user()->id)
->where('favoritable_id', $product_id)
->get();
return $result;
}
From the code above, I'm using parameter product_id to add, delete and get data favorite
What I want to ask here is : Whether the above is the correct way to add, delete and get data using polymorphic relationship?
Or is there a better way to do that?

How to make dynamic query in laravel 5 with model and controller

i have Add query in codeigniter like this:
in controller:
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log=$this->model->add_data($data);
And in model add_data function like this:
function add_data($data)
{
return $this->db->insert($data['table'],$this->security->xss_clean($data['val']));
}
But In Laravel 5 I have:
$name=$Request->input('name');
$lname=$Request->input('lname');
$myItems = array(
'first_name'=>$name,
'last_name'=>$lname
);
DB::table("tbl_user")->insert($myItems);
My question is, how can we make table field dynamic in Laravel and call that function through model.
Also, how can I call that function from model? Any help please. I want a dynamic query
You can write a helper function
//create a helper function
function addModelData($arrayData = [])
{
return \DB::table($arrayData['table'])->insert($arrayData['val']));
}
//in your controller or any place you like
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log = addModelData($data);
You could create a model as described in official documentation:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'tbl_user';
// If your primary key is not 'id'
protected $primaryKey = 'model_id';
}
Now in your controller you can use this model:
namespace App\Http\Controller;
use App\User;
use Illuminate\Http\Request;
class MyController extends Controller {
public function myAction(Request $request){
$user = new User();
$user->last_name = $request->input('lname');
$user->first_name = $request->input('name');
$user->save();
}
}
You also could use mass assignment. But before you have to set the $fillable attribute in your model:
protected $fillable = ['first_name', 'last_name'];
Now you can use mass assignment in your controller:
$user = User::create([
'first_name' => $request->input('name'),
'last_name' => $request->input('lname')
]);
// alternatively:
$user = User::create($request->only(['name', 'lname']));

Return count of relation along with parent data

Hello i have two tables in my database:
categories
events
I have a page that displays a list of all categories. However i want to display a count of how many events are in each category next to the category title.
eg.:
comedy (10)
music (5)
The relationship between these two models is one to many, as one category can have zero or more events.
My question is how do i fetch the total number of events for each category along with the category data when i execute this code:
$categories = Category::get();
What i have tried so far:
class Categories extends Model implements SluggableInterface
{
use SluggableTrait;
protected $sluggable = [
'build_from' => 'name',
'save_to' => 'slug',
'on_update' => true,
];
protected $table = 'categories';
public function events() {
return $this->hasMany('App\Models\Events', 'category_id');
}
public function eventsCountRelation() {
return $this->hasMany('App\Models\Events', 'category_id')->selectRaw('id, count(*) as count');
}
public function eventsCountAttribute() {
return $this->eventsCountRelation->count();
}
}
The error i get:
foreach($categories as $categoriy) {
echo $category->name.' ('.$category->events->count().')';
}
Returns something like:
comedy (10)
music (5)
If you want to print it in a view you don't need to load them in the controller.
But if you want to print it as json you need something like this:
$categories = Category::all();
In the Category Model you need to add this:
protected $appends = ['counter'];
public function getCounterAttribute() {
return $this->events->count();
}
Update your class like this:
class Categories extends Model implements SluggableInterface
{
use SluggableTrait;
protected $sluggable = [
'build_from' => 'name',
'save_to' => 'slug',
'on_update' => true,
];
protected $appends = [
'counter'
];
protected $table = 'categories';
public function events() {
return $this->hasMany('App\Models\Events', 'category_id');
}
public function eventsCounterAttribute() {
return $this->events->count();
}
}
You don't need more.

Using properly of eager loading

I have two tables: contracts and contractitems. I want to display all my Contract items and have a search for searching the contractor name.
Contracts
id
contract_code
contractor_name
ContractItems
id
contracts_id
item_name
class ContractItems extends Eloquent {
protected $table = 'ContractItems';
protected $guarded = [ 'id' ];
public $timestamps = false;
public function contract()
{
return $this->hasOne('Contracts', 'id', 'contracts_id');
}
}
$x = ContractItems::with(array('contract' => function($query){
$query->where('contractor_name', 'LIKE' , '%name%');
}))->take(1)->get();
I tried the code above but it is not displaying the correct data.

Resources