laravel pivot table column not found while try to update - laravel-5

Problem is when I try to update the book table, it shows error
unknown column 'publisher'
I have a book_publisher pivot table.
What code do I have to write and where do I have to write it?
class Book extends Model
{
// protected table='book';
public function authors()
{
return $this->belongsToMany(Author::class)->withPivot('type');
}
// public function author($type)
// {
//
// return $this->authors()->where('type', $type)->first();
// }
public function author()
{
return $this->authors()->where('type', 'Author')->first();
}
public function illustrator()
{
return $this->authors()->where('type', 'Illustrator')->first();
}
public function translator()
{
return $this->authors()->where('type', 'Translator')->first();
}
public function editor()
{
return $this->authors()->where('type', 'Editor')->first();
}
// foreach ($book->authors as $author)
// {
// $author->type;
// }
public function publishers()
{
return $this->belongsToMany(Publisher::class);
}
}
bookcontroller
public function edit($id)
{
$book=Book::findOrFail($id);
$category=Category::pluck('name', 'id');
$publishers=Publisher::all();
foreach($publishers as $publisher)
{
$publisher->id=$publisher->name;
}
return view('books.edit', compact('book','category','publishers'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$book=Book::findOrFail($id);
$book->Update($request->all());
Book::find($id)->publisher()->updateExistingPivot($request->only('publisher_id'));
return redirect('books');
}
Please also tell if I have to edit edit.blade.php as well.

Check these ways
$books = Book::find($id);
$books->publisher()->updateExistingPivot('publisher_id',
['publisher_id' => publisher_id],false));
or something like this
$books = Book::find($id);
$publisher = $books->publisher;
$publisher->pivot->publisher_id = $request->publisher_id;
$publisher->pivot->save();

Related

Can't do pagination in laravel

I need to do a pagination of the data I retrieve from the DB but I get this error:
Call to undefined method App\Models\DataFromRasp::table()
I followed the Laravel documentation but I still getting this error
My controller is this:
class DeviceController extends Controller
{
public function index()
{
$data=Device::all();
return view('backend.auth.user.device', compact("data"));
}
public function create()
{
}
public function store(Request $request)
{
}
public function show(Device $deviceID)
{
$device = Device::firstWhere('id', $deviceID);
return view('backend.auth.user.singleDevice', compact("device"));
}
public function edit(Device $device)
{
//
}
public function update(Request $request, Device $device)
{
//
}
public function destroy(Device $device)
{
//
}
public function visualizeData()
{
$data=DataFromRasp::table('data_from_rasp')->simplePaginate(10);
return view('backend.auth.user.dictionary', compact("data"));
}
public function getData(Request $request)
{
$m_data = $request->get('m_data');
$r_data = $request->get('r_data');
DataFromRasp::create(['MAC' => $m_data, 'RSSI' => $r_data]);
if(($m_data == 'C4:A5:DF:24:05:7E' or $m_data == '70:1C:E7:E4:71:DA') and Device::where('MAC_ADDR', $request->m_data)->doesntExist()){
Device::create(['MAC_ADDR' => $m_data]);
}
}
public function scan()
{
$process = new Process(['python2','C:\Simone\Università\Smart IoT Devices\Lab_Raspy\Bluetooth\prova.py']);
$process->run();
if (!$process->isSuccessful()) { throw new ProcessFailedException($process); }
return redirect()->route('dict');
}
}
The route is:
Route::get('dict', [DeviceController::class, 'visualizeData'])->name('dict');
Can someone help me?
try $data = DataFromRasp::paginate(10)

Return collection with custom resolver/data provider on ApiPlatform with GraphQL

I work with PHP - Symfony 5.
I would like to return a collection with graphQL on Api Platform but I have a problem :
"debugMessage": "Service \"App\\DataProvider\\CompaniesCollectionDataProvider\" not found: the container inside \"Symfony\\Component\\DependencyInjection\\Argument\\ServiceLocator\" is a smaller service locator that only knows about the \"App\\Resolver\\CheckRecruiterQueryResolver\", \"App\\Resolver\\ForgotRecruiterQueryResolver\" and \"App\\Resolver\\JobBoard\\FindOffersByCompanyQueryResolver\" services.",
First I had created a resolver but looking at the documentation, I realized that it was necessary to make a data provider.
Unfortunately that did not solve the problem, I still have the same error message...
My custom data Provider :
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use App\Entity\Candidate;
use App\Entity\Company;
use Doctrine\Persistence\ManagerRegistry;
class CompaniesCollectionDataProvider implements CollectionDataProviderInterface
{
private $doctrine;
public function __construct(ManagerRegistry $doctrine)
{
$this->doctrine = $doctrine;
}
public function getCollection
(string $resourceClass, string $operationName = null, array $context = [])
{
$candidateId = $context['filters']['candidate_id'];
$candidate = $this->doctrine->getRepository(Candidate::class)
->findOneBy(['id' => $candidateId]);
if(empty($candidate->getPosition()))
{
$companies = $this->doctrine->getRepository(Company::class)
->findByStoreIsNational();
// return companies where stores related = is_national
// getCollection doit retourner un array
return $companies;
}
$companies = $this->doctrine->getRepository(Company::class)
->findByStoreIsNational();
return $companies;
}
}
My entity :
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\DataProvider\CompaniesCollectionDataProvider;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ApiResource(graphql={
* "search"={
* "collection_query"=CompaniesCollectionDataProvider::class,
* "args"={
* "candidate_id"={"type"="Int!", "description"="Candidate_id"}
* }
* },
* "create", "update", "delete", "collection_query", "item_query"
* })
*
* #Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
* #ORM\Entity(repositoryClass="App\Repository\CompanyRepository")
* #ORM\Table(name="companies")
* #UniqueEntity("name")
*/
class Company
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Media", mappedBy="company")
*/
private $logo;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $createdAt;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $deletedAt;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Store", mappedBy="company")
*/
private $stores;
public function __construct()
{
$this->stores = new ArrayCollection();
$this->stories = new ArrayCollection();
$this->logo = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getLogo(): ?string
{
return $this->logo[0];
}
public function setLogo(string $logo): self
{
$this->logo = $logo;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getDeletedAt(): ?\DateTimeInterface
{
return $this->deletedAt;
}
public function setDeletedAt(?\DateTimeInterface $deletedAt): self
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* #return Collection|Store[]
*/
public function getStores(): Collection
{
return $this->stores;
}
public function addStore(Store $store): self
{
if (!$this->stores->contains($store)) {
$this->stores[] = $store;
$store->setCompany($this);
}
return $this;
}
public function removeStore(Store $store): self
{
if ($this->stores->contains($store)) {
$this->stores->removeElement($store);
// set the owning side to null (unless already changed)
if ($store->getCompany() === $this) {
$store->setCompany(null);
}
}
return $this;
}
public function addLogo(Media $logo): self
{
if (!$this->logo->contains($logo)) {
$this->logo[] = $logo;
$logo->setCompany($this);
}
return $this;
}
public function removeLogo(Media $logo): self
{
if ($this->logo->contains($logo)) {
$this->logo->removeElement($logo);
// set the owning side to null (unless already changed)
if ($logo->getCompany() === $this) {
$logo->setCompany(null);
}
}
return $this;
}
}
My repository :
class CompanyRepository extends AbstractRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Company::class);
}
public function findByStoreIsNational() {
return $this->createQueryBuilder('c')
->leftJoin('c.stores', 's')
->where('s.isNational = true')
->getQuery()
->getResult();
}
I thank you in advance for your help,
Regards,
Romain
As stated in the documentation for custom queries, you need to create a custom resolver, not a custom data provider.
CompaniesCollectionDataProvider should become CompanyCollectionResolver and should implement QueryCollectionResolverInterface.

How To Display Product API by categories using laravel

My expected JSON format:
This is my expected JSON format, I have a product table along with products related table. I want to show products in categories wise.
Product Table:
Category Table:
Here is my product model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = ['id'];
private $minimum_price;
/**
* Get the products image.
*
* #return string
*/
public function getImageUrlAttribute()
{
if (!empty($this->image)) {
$image_url = asset('/storage/img/product/' . $this->image);
} else {
$image_url = asset('/img/default.png');
}
return $image_url;
}
public function product_variations()
{
return $this->hasMany(\App\ProductVariation::class);
}
/**
* Get the brand associated with the product.
*/
public function brand()
{
return $this->belongsTo(\App\Brands::class);
}
/**
* Get the unit associated with the product.
*/
public function unit()
{
return $this->belongsTo(\App\Unit::class);
}
/**
* Get category associated with the product.
*/
public function category()
{
return $this->belongsTo(\App\Category::class);
}
/**
* Get sub-category associated with the product.
*/
public function sub_category()
{
return $this->belongsTo(\App\Category::class, 'sub_category_id', 'id');
}
/**
* Get the brand associated with the product.
*/
public function product_tax()
{
return $this->belongsTo(\App\TaxRate::class, 'tax', 'id');
}
/**
* Get the variations associated with the product.
*/
public function variations()
{
return $this->hasMany(\App\Variation::class);
}
/**
* If product type is modifier get products associated with it.
*/
public function modifier_products()
{
return $this->belongsToMany(\App\Product::class, 'res_product_modifier_sets', 'modifier_set_id', 'product_id');
}
/**
* If product type is modifier get products associated with it.
*/
public function modifier_sets()
{
return $this->belongsToMany(\App\Product::class, 'res_product_modifier_sets', 'product_id', 'modifier_set_id');
}
/**
* Get the purchases associated with the product.
*/
public function purchase_lines()
{
return $this->hasMany(\App\PurchaseLine::class);
}
public function images()
{
return $this->hasMany(ProductImage::class);
}
public function attributes()
{
return $this->hasMany(ProductAttribute::class);
}
public function attributesWithoutDefault()
{
return $this->hasMany(ProductAttribute::class)->where('attribute_id', '>', 4);
}
public function vendor_product()
{
return $this->hasMany(VendorProduct::class, 'product_id', 'id');
}
public function origin()
{
return $this->belongsTo(ProductOrigin::class);
}
public function defaultAttributes()
{
return $this->hasMany(ProductAttribute::class)->where('attribute_id', '<=', 4);
}
public function notes()
{
return $this->hasMany(ProductNote::class);
}
public function additionalCategory()
{
return $this->belongsTo(\App\Category::class, 'additional_category', 'id');
}
public function getAdditionalCategoryNameAttribute()
{
$additional_category = $this->additionalCategory;
return $additional_category ? $additional_category->name : null;
}
public function industries()
{
return $this->belongsToMany(Industry::class, 'product_industries');
}
public function getCatalogUrlAttribute()
{
return asset('/uploads/'. constants('product_catalog_path') . '/' . $this->catalog_brusher);
}
public function getSpecSheetUrlAttribute()
{
return asset('/uploads/'. constants('product_spec_sheet_path') . '/' . $this->spec_sheet);
}
public function relatedProducts()
{
return $this->belongsToMany(Product::class, 'related_products', 'product_id', 'related_product_id');
}
private function setMinPrice()
{
if (is_null($this->minimum_price)) {
$this->minimum_price = $this->vendor_product->min('price');
}
return $this->minimum_price;
}
public function getMinPriceAttribute()
{
return $this->setMinPrice();
}
public function getMinPriceVendorAttribute()
{
$min_price = $this->setMinPrice();
if (is_null($min_price)) return null;
$min_vendor_product = $this->vendor_product->firstWhere('price', $min_price);
return Contact::find($min_vendor_product->vendor_id);
}
/**
* Get the unit quantity associated with the product.
*/
public function unitQuantity()
{
return $this->belongsTo(\App\UnitQuantity::class);
}
}
you should join the same table more than once, every time you join,
you join with suitable alias name:
$list = Product::
leftJoin('categories as mainCategory','products.category_id','mainCategory.id')
->leftJoin('categories as subCategory','products.sub_category_id','subCategory.id')
->leftJoin('categories as additionalCategory','products.additional_category','additionalCategory.id')
->select(['products.*','mainCategory.name as mainCategoryName','subCategory.name as subCategoryName','additionalCategory.name as additionalCategoryName'])->get();
please note that your column 'products.additional_category' should be named
products.additional_category_id
see:
https://stackoverflow.com/a/21835059/10573560

Argument 1 passed to Illuminate\\Database\\Eloquent\\Model::__construct() must be of the type array, object given

I want to add product to wishlist and following repository pattern to store product id and user id of the user who wants to add product to his wishlist but when i run my code i get
Argument 1 passed to
Illuminate\Database\Eloquent\Model::__construct() must be of the
type array, object given, called in .... WishlistRepository.php
This is my Code:
WishlistController.php
namespace App\Http\Controllers\Site;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Contracts\WishlistContract;
class WishlistController extends Controller
{
protected $wishlistRepository;
public function __construct(WishlistContract $wishlistRepository)
{
$this->wishlistRepository = $wishlistRepository;
}
public function show()
{
$wishlist = $this->wishlistRepository->listWishlist();
return view('site.pages.wishlist', compact('wishlist'));
}
public function addToWishlist(Request $request)
{
$productID=$request->p_id;
$userID=auth()->user()->id;
$data=array('product_id'=>$productID,'user_id'=>$userID);
$wishlist = $this->wishlistRepository->addToWishlist($data);
}
}
WishlistContract.php
<?php
namespace App\Contracts;
/**
* Interface WishlistContract
* #package App\Contracts
*/
interface WishlistContract
{
/**
* #param string $order
* #param string $sort
* #param array $columns
* #return mixed
*/
public function listWishlist(string $order = 'id', string $sort = 'desc', array $columns = ['*']);
/**
* #param array $params
* #return mixed
*/
public function addToWishlist(array $params);
/**
* #param $id
* #return mixed
*/
//public function deleteFromWishlist($id);
/**
* #param array $params
* #return bool
*/
//public function updateWishlist(array $params);
}
?>
WishlistRepository.php
<?php
namespace App\Repositories;
use App\Models\Wishlist;
use App\Traits\UploadAble;
use Illuminate\Http\UploadedFile;
use App\Contracts\WishlistContract;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
/**
* Class WishlistRepository
*
* #package \App\Repositories
*/
class WishlistRepository extends BaseRepository implements WishlistContract
{
use UploadAble;
public function __construct(Wishlist $model)
{
parent::__construct($model);
$this->model = $model;
}
public function listWishlist(string $order = 'id', string $sort = 'desc', array $columns = ['*'])
{
return $this->all($columns, $order, $sort);
}
public function addToWishlist(array $params)
{
try {
$collection = collect($params);
$wishlist = new Wishlist($collection);
$wishlist->save();
return $wishlist;
} catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
public function removefromWishlist($id)
{
$wishlist = $this->findAttributeById($id);
$wishlist->delete();
return $wishlist;
}
public function updateToWishlist(array $params)
{
$wishlist = $this->findWishlistById($params['id']);
$collection = collect($params)->except('_token');
$is_filterable = $collection->has('is_filterable') ? 1 : 0;
$is_required = $collection->has('is_required') ? 1 : 0;
$merge = $collection->merge(compact('is_filterable', 'is_required'));
$wishlist->update($merge->all());
return $wishlist;
}
}
?>
view (script):
$('body').on('click', '.wishlist', function(e){
e.preventDefault();
var product_id=$(this).attr('data-wishlist');
jQuery.ajax({
url: "{{ url('/add-wishlist') }}",
method: 'post',
data: {
"p_id": product_id,"_token": "{{ csrf_token() }}",
},
success: function(result){
// input.val(result.status);
}});
});
You may fix it by removing this line
$collection = collect($params);
You don't need it : because collect will convert your array to Illuminate\Support\Collection object.
Class WishlistRepository
public function addToWishlist(array $params) {
try {
$wishlist = new Wishlist($params);
// OR
// $wishlist = new Wishlist();
// $wishlist->column = $params['column'];
//...
$wishlist->save();
return $wishlist;
} catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
public function addToWishlist(array $params)
{
try {
$collection = collect($params);
$wishlist = new Wishlist($collection);
$wishlist->save();
return $wishlist;
} catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
You are passing $collection to a model whe it's expecting array with values.
When you are making the new instance of Wishlist pass in the array as it is, instead of creating and passing a collection
public function addToWishlist(array $params)
{
try {
return (new Wishlist($params))->save();
} catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}

Laravel - Prevent from create empty key in database

I have a table where I keep all the settings that will be used on the website, they are saved in the cache, I'm trying to upload the favicon, however when uploading the image the favicon row is updated and an empty key value with the temp path is created at the same time, how can I solve this?
You can see the empty field in the image...
Route
Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController#update']);
Model
class Setting extends Model
{
protected $table = 'settings';
public $timestamps = false;
protected $fillable = ['value'];
}
Controller
class AdminConfiguracoesController extends AdminBaseController
{
private $repository;
public function __construct(SettingRepository $repository){
parent::__construct();
$this->repository = $repository;
}
public function update(Request $request, Factory $cache)
{
$settings = $request->except('_method', '_token');
$this->repository->update($settings);
$cache->forget('settings');
return redirect()->back();
}
}
Repository
class SettingRepository{
private $settings;
public function __construct(Setting $settings)
{
$this->settings = $settings;
}
public function update($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
if( $name == "website_favicon" ){
$imageName = $key['website_favicon']->getClientOriginalName();
$this->update($name, asset('public/images/website/'.$imageName));
$key['website_favicon']->move(
base_path() . '/public/images/website/', $imageName
);
} else{
$this->update($name, $value);
}
}
}
$setting = $this->settings->firstOrCreate(['name' => $key]);
$setting->value = $value;
$setting->save();
}
public function lists()
{
return $this->settings->lists('value', 'name')->all();
}
}
The problem is a missing return statement after the foreach loop in your repository. The code after the loop will be executed. $key is an array and $value is the temp value of the uploaded file, which will be set inside the loop.
As I mentioned in my comment, you shouldn't use the repository to upload files. Do it in your controller instead:
AdminConfiguracoesController.php
class AdminConfiguracoesController extends AdminBaseController
{
private $repository;
public function __construct(SettingRepository $repository)
{
parent::__construct();
$this->repository = $repository;
}
public function update(Request $request, Factory $cache)
{
$settings = $request->except('_method', '_token', 'website_favicon');
if ($request->hasFile('website_favicon'))
{
$this->uploadImage($request->file('website_favicon'), 'website_favicon');
$cache->forget('website_favicon');
}
$this->repository->update($settings);
$cache->forget('settings');
return redirect()->back();
}
private function uploadImage(UploadedFile $image, $key)
{
$image->move(public_path('images/website'), $image->getClientOriginalName());
$this->repository->update($key, $image->getClientOriginalName());
}
}
SettingRepository.php
class SettingRepository
{
private $settings;
public function __construct(Setting $settings)
{
$this->settings = $settings;
}
public function update($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
$this->update($name, $value);
}
return; // This was missing!
}
$setting = $this->settings->firstOrCreate(['name' => $key]);
$setting->value = $value;
$setting->save();
}
public function lists()
{
return $this->settings->lists('value', 'name')->all();
}
}
You can refactor this even further to use a Job that uploads the image, but this would be overkill for now.

Resources