I am trying to relate the restaurant_id with the dishes - php

I have a one to many relationship between two tables, restaurant and dishes. I cannot associate the restaurant id with the dishes. I had to put the user_id but doing so if the user has more than one restaurant all the dishes would be mixed. so i should replace the user_id with the restaurant_id
DishController
class DishController extends Controller
{
public function index()
{
$dishes = Dish::all();
$restaurant = Restaurant::all();
$dishes = Dish::where('restaurant_id', Auth::id())->get();
return view('admin.dishes.index', compact('dishes', 'restaurant'));
}
public function create()
{
return view('admin.dishes.create');
}
public function store(Request $request, Restaurant $id)
{
$data = $request->all();
$data["restaurant_id"]= Auth::id();
/* $data['slug'] = Str::slug($data['name'], '-'); */
$new_dish = new Dish();
$new_dish->fill($data);
$new_dish->save();
return redirect()->route('admin.dishes.index', $new_dish);
}
public function show($id)
{
$dish = Dish::find($id);
if(!$dish){
abort(404);
}
return view('admin.dishes.show', compact('dish'));
}
public function edit($id)
{
$dish = Dish::find($id);
if (!$dish) {
abort(404);
}
return view('admin.dishes.edit', compact('dish'));
}
public function update(Request $request, Dish $dish)
{
$data = $request->all();
$dish->update($data);
return redirect()->route('admin.dishes.show',$dish);
}
public function destroy($id)
{
//
}
}
Dish model
class Dish extends Model
{
protected $fillable = [
'name', 'ingredients', 'price', 'cover', 'visible','restaurant_id'
];
public function restaurant(){
return $this->belongsTo('App\Restaurant');
}
public function orders(){
return $this->belongsToMany('App\Order');
}
}

You can try by adding a hidden field to restaurant_id in your view form
<input type="hidden" name="restaurant_id" value={{ $restaurant->id }}>
then, in your store method
$restaurant = Restaurant::find($request->restaurant_id);
$restaurant->dishes()->create( //Your Atribbutes here//);

Related

How to make each authenticated user only see their own product

I'm trying to figure out how an authenticated user can only see products from their dashboard, i.e., every user has unique products list, and be able to create his own products. What i see now is if any user creates,delete or list product all users get affected.
I have tried to search other tutorials but didn't get the solution.
web.php
Route::group(['prefix'=>'seller', 'middleware'=> ['auth']],function() {
Route::get('/',function (){
return view('seller.index', compact('products'));
});
Route::resource('product', 'productController');
Route::get('/seller', 'ProductController#seller')->name('seller');
});
User.php
public function products()
{
return $this->hasMany(Products_model::class);
}
Products_model
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['pro_name','pro_price','pro_info','image','stock','category_id'];
}
ProductController
class productController extends Controller
{
public function index()
{
$products=products_model::all();
return view('seller.product.index',compact('products'));
}
public function user()
{
return $this->belongsTo(User::class);
}
public function create()
{
return view('seller.product.create');
}
public function seller()
{
$products=products_model::all();
return view('seller.product.index',compact('products'));
}
public function store(Request $request)
{
$formInput=$request->except('image');
$this->validate($request, [
'pro_name'=> 'required',
'pro_price'=> 'required',
'pro_info'=> 'required',
'image'=>'image|mimes:png,jpg,jpeg|max:10000'
]);
$image=$request->image;
if($image){
$imageName=$image->getClientOriginalName();
$image->move('images', $imageName);
$formInput['image']=$imageName;
}
products_model::create($formInput);
return redirect()->back();
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
$deleteData=products_model::findOrFail($id);
$deleteData->delete();
return redirect()->back();
}
}
I want every user to have their unique dashboard, which means if a user deletes or creates a product it should only show in his dashboard without affecting others.
Wherever you need to display only the authenticated user's products, change your query to filter out other peoples products:
public function controllerAction(Request $request)
{
$userId = $request->user()->id;
// or $userId = Auth::id(); (Via the Auth facade)
// or $userId = auth()->id();
$products = products_model::where('user_id', $userId)->get();
}
In your product model you need add the user_id to able relate the tables user with products:
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['user_id', 'pro_name','pro_price','pro_info','image','stock','category_id'];
}
After in you controller you can filter the products by user and return these, at create new product can get the user logged id and put in new product

many to many relation returns null in laravel

I have a many to many relation between the tables user and clinic and the third table is user_clinics. All three tables returns their values perfectly individually, but when i call App\User::find(1)->clinics or its inverse it returns null. Moreover, user_clinic has user_id and clinic_id and also previlage_id as a foreign key.
public function users() {
return $this->belongsToMany(User::class,'user_clinics','user_id','clinic_id');
}
public function clinics() {
return $this->belongsToMany(Clinic::class,'user_clinics','clinic_id','user_id');
}
public function adminDashboard(Request $request) {
$clinic = new Clinic();
$User_clinic = new User_clinic();
$user = new User();
$clinic->name = $request->name;
$clinic->address = $request->address;
if($request->hasFile('logo')) {
$fileName = $request->logo->getClientOriginalName();
$request->logo->storeAs('public/logos',$fileName);
$clinic->logo = $request->logo;
}
$clinic->save();
$User_clinic->user_id = auth::user()->id;
$test=$User_clinic->clinic_id = $clinic->id;
//now hardcoded previlage_id but deal with it in future...
$User_clinic->previlage_id = 1;
$User_clinic->save();
$test= $clinic::find(2)->users;
dd($test);
//return view("admin.dashboard.dashboardFirstPage");
}
Your relationship is not quiet right:
public function users() {
return $this->belongsToMany(User::class,'user_clinics','user_id','clinic_id');
}
public function clinics() {
return $this->belongsToMany(Clinic::class,'user_clinics','clinic_id','user_id');
}
It should be like below:
In User model:
public function clinics() {
return $this->belongsToMany(Clinic::class,'user_clinics','user_id','clinic_id');
}
In Clinic model:
public function users() {
return $this->belongsToMany(User::class,'user_clinics','clinic_id','user_id');
}

Use eloquent relation on models returning by another method

I have a Category model which has belongsToMany relation with Product model via a pivot table called product_to_category
I can get all products in a Category with $category->products() and then apply a Filter scope to it to filter the result with parameters given in Request like this:
When I send this request :
http://site.dev/category/205?product&available&brand
I apply the parameters like this:
Category::find($id)->products()->filter($request)
The problem is when I want to get all product in a category and its children. The existing products relation gives me products in only given category.
I tried to modify the products() method in Category model as this:
public function products()
{
return DB::table('oc_product')
->join('oc_product_to_category', 'oc_product_to_category.category_id', '=', 'oc_product_to_category.category_id')
->join('oc_category_path', 'oc_category_path.category_id', '=', 'oc_category.category_id')
->whereIn('oc_product_to_category.category_id', $this->children(true));
}
But when I this code :
Category::find($id)->products()->filter($request)
I get this exception error:
(1/1) BadMethodCallException
Call to undefined method Illuminate\Database\Query\Builder::filter()
I know that filter scope is defined in Model class, but how can I apply that filter scope to QueryBuilder which is returned by modified products method?
Here are my classes :
Product model:
class Product extends Model {
public function scopeFilter( $request, QueryFilter $filters ) {
return $filters->apply( $request );
}
public function categories() {
return $this->belongsToMany( Category::class, 'product_to_category', 'product_id', 'category_id' );
}
}
Category model:
class Category extends Model
{
public function scopeFilter($query, QueryFilter $filters)
{
return $filters->apply($query);
}
public function children($id_only = false)
{
$ids = $this->hasMany(CategoryPath::class, 'path_id', 'category_id')
->join('category', 'category.category_id', '=', 'category_path.category_id')
->where('category.status', 1)
->pluck('category.category_id');
if ($id_only)
return $ids;
return self::find($ids);
}
public function parent()
{
$parent = DB::Select("SELECT cp.path_id AS category_id FROM category_path cp LEFT JOIN category_description cd1
ON (cp.path_id = cd1.category_id AND cp.category_id != cp.path_id)
WHERE cd1.language_id = '2' AND cp.category_id = " . $this->category_id);
return $parent;
}
public function products()
{
return $this->belongsToMany(Product::class, 'product_to_category', 'category_id', 'product_id');
}
}
QueryFilter class:
abstract class QueryFilter {
protected $request;
protected $builder;
public function __construct( Request $request ) {
$this->request = $request;
}
public function filters() {
return $this->request->all();
}
public function apply( Builder $builder ) {
$this->builder = $builder;
foreach ( $this->filters() as $name => $value) {
if (method_exists($this, $name)) {
call_user_func_array([$this, $name], array_filter([$value]));
}
}
return $this->builder;
}
}
CategoryFilter class:
class CategoryFilters extends QueryFilter
{
public function id($id)
{
return $this->builder->where('category_id', $id);
}
public function procons()
{
return $this->builder->with('pros', 'cons');
}
public function available()
{
return $this->builder->where('quantity', '>', 0);
}
public function optionValues()
{
return $this->builder->with('optionValues');
}
public function description()
{
return $this->builder->with('description');
}
public function images()
{
return $this->builder->with('images');
}
public function order($order)
{
$params = explode(',', $order);
$order = isset($params[0]) ? $params[0] : null;
$way = isset($params[1]) && strtolower($params[1]) == 'desc' ? $params[1] : 'asc';
if ($order) {
return $this->builder->orderBy($order, $way);
}
return $this->builder;
}
}

How to associate a model with two or more other models in Laravel

I need to associate some models with at least two other models in an app that I'm developing, but I can't do the association in the controllers.
Here's the code.
UserModel
public function prices() {
return $this->hasMany(PriceClass::class);
}
PriceModel
public function user() {
return $this->belogsTo(ClassOfTheUser::class);
}
public function price_lines() {
return $this->hasMany(PriceLinesClass::class);
}
AreaModel
public function price_lines() {
return $this->hasMany(PriceLineClass::class);
}
PriceLinesModel
public function area() {
return $this->belongsTo(AreaClass::class);
}
public function price() {
return $this->belongsTo(PriceClass::class);
}
How may I do the creation of the Price, if I can't do something like:
public function store(Request $request) {
if ($request->ajax()) {
$user = UserClass::findOfFail($request->input("user_id"));
$user->prices()->save(new PriceClass());
$price = $user->prices()->lastest()->first();
foreach($request->input("price_lines") as $price_line) {
$area = AreaClass::findOrFail($price_line["area_id"]);
$area->price_lines()->save(new PriceLineClass());
$price_line_instance = $area->price_lines()->lastest()->first();
$price->price_lines()->save($price_line_instance);
}
}
}

Get distinct attribute from database in Laravel

I have two tables, one called "products" and another "product_brands".
A product has one brand, and a brand can belong to many products.
I have:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function brand()
{
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->brand;
return $ar;
}
public function getBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
}
And my controller:
class ProductsController extends BaseController {
public function index($type_id) {
$Product = new Product;
$products = $Product->where('type_id', $type_id)->get();
return View::make('products.products', array('products' => $products));
}
}
Ideally I would like the column from "product_brands" to be in the same array as the columns from "products", hence why I am trying that stuff with toArray() and getBrandAttribute() but it isn't working.
How can I do this?
I'm sure the getBrandAttribute accessor collides with the brand relationship. Try this instead:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function productBrand() {
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function getBrandAttribute() {
$brand = $this->productBrand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
protected $appends = array('brand'); // this makes Laravel include the property in toArray
}
You should change your accessor to other name:
public function getSpecBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
and in toArray you should then use:
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->spec_brand;
return $ar;
}
That's because you shouldn't create fields with the same name as relationship name.
In addition as it's one to many relationship, probably for brand() you should use belongsTo and not hasOne

Categories