I have been dealing with this ErrorException when trying to add data to a pivot table in Laravel.
When I use a dummy array data ie
$service->features()->attach([1,2]); it works but when I use values from an array variable ie. $service->features()->attach($featuresIds); wheareas $featuresIds has the value [1,2] it throws:
ErrorException (E_WARNING)
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array.
My Service model class has:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Service extends Model {
protected $table = 'services';
public $timestamps = false;
protected $fillable = array('title', 'category', 'description', 'image', 'delivery_time', 'features', 'price', 'supplier', 'user_id');
protected $visible = array('id','title', 'category', 'description', 'image', 'delivery_time', 'features', 'price', 'supplier');
protected $dates = ['delivery_time'];
// public function features()
// {
// return $this->hasMany('Feature', 'id');
// }
public function supplier()
{
return $this->hasOne('Supplier', 'id');
}
public function category()
{
return $this->belongsTo('Category', 'id');
}
public function user()
{
return $this->belongsTo('App\User');
}
public function features()
{
return $this->belongsToMany('App\Feature')->withTimestamps();
}
}
My Feature model class has:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Feature extends Model {
protected $table = 'features';
// public $timestamps = true;
protected $fillable = array('description');
protected $visible = array('id','description');
public function services()
{
return $this->belongsTomany('App\Service');
}
}
My controller store method has:
public function store(ServiceRequest $request)
{
$service = Auth::user()->services()->create($request->all());
$featuresIds = $request->input('features');
$service->features()->attach($featuresIds);
return redirect('admin/service');
}
I have searched through many solutions online, but could not find a way to solve it. Help if you can detect what I am doing wrong.
Related
there is a (card model) bleongsToMany contacts, and there is a (contact model) is bleongsToMany cards, I want when (card) get updated his children in the middle table in the relation became removed.
I'm trying to do this by using (the observer), I did all steps correctly but the issue is:
when (card model) updated his children still exist in the middle table of the relationship, I want to remove them when any update on the card.
Route:
Route::get('/test',function(){
$card = \App\Models\Card::find(1);
$card-> update([
'name' => 'firstCard1',
'user_name' =>1,
]);
return true;
});
Observer:
<?php
namespace App\Observers;
use App\Models\Card;
class CardObserver
{
public function updated(Card $card)
{
$card -> contact()-> delete();
}
}
Card Model:
<?php
namespace App\Models;
use App\Observers\CardObserver;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Card extends Model
{
use HasFactory;
protected $fillable = [
'name',
'user_id ',
];
public $timestamps = true;
protected $hidden = ['pivot'];
public function contact()
{
return $this->belongsToMany(Contact::class, 'card_contacts', 'card_id');
}
public function connection()
{
return $this->belongsTo(Connection::class, '');
}
protected static function boot()
{
parent::boot();
Card::observe(CardObserver::class);
}
}
Contact Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
use HasFactory;
protected $fillable = [
'provider_id',
'user_id',
'contact_string'
];
public $timestamps = true;
protected $hidden = ['pivot'];
public function card(){
return $this->belongsToMany(Card::class,'card_contacts','contact_id');
}
public function user(){
return $this->belongsTo(User::class,'user_id');
}
public function provider(){
return $this->belongsTo(Provider::class,'provider_id');
}
}
Card_contact Model (the pivot table):
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CardContact extends Model
{
use HasFactory;
protected $fillable = [
'card_id',
'contact_id',
];
public $timestamps = true;
}
any help please?
im using laravel 7.24 and php 7.4 on my project
What i want to is fundementally creating relations between 3 table and using them in 'one' query.
to be specific i need to access 'ordered products' from my order detail page.
public function orderdetail($id)
{ //certainorder model access to 'ShoppingCard'model from below
$orderDetails = CertainOrder::with('ShoppingCard.shoppingCardProducts.product')
->where('ShoppingCard.id' , $id)->firstorFail();
return view('orderdetails', compact ('orderDetails'));
}
CertainOrder model access to 'ShoppingCard' model from top and in the ShoppingCard model it contains shoppingCardProducts function which you will see in below and with shoppingCardProducts function my 'products' table had a relation. the problem is something in relations is wrong and i can't get data from shoppingcardproduct
class ShoppingCard extends Model
{
protected $table = "shopping_card";
protected $fillable = ['id', 'user_id', 'created_at','updated_at'];
public function shoppingCardProducts()
{
return $this->hasMany('App\ShoppingCardProduct');
}
class CertainOrder extends Model
{
protected $table = "certain_orders";
protected $guarded = [];
public function shoppingCard()
{
return $this->belongsTo(ShoppingCard::class, 'sepet_id');
//sepet_id is a foreign key.
}
class ShoppingCardProduct extends Model
{
use SoftDeletes;
protected $table = "shopping_card_product";
protected $fillable = ['id', 'sepet_id', 'urun_id','quantity','price','status','created_at','updated_at','deleted_at'];
public function product()
{
return $this->belongsTo('App\Product');
}
I think you missed it somewhere in the code
class ShoppingCard extends Model
{
protected $table = "shopping_card";
protected $fillable = ['id', 'user_id', 'created_at','updated_at'];
public function shoppingCardProducts()
{
return $this->hasMany('App\ShoppingCardProduct');
}
public function CertainOrder(){
return $this->hasMany('path\to\model');
}
public function ShoppingCardProduct(){
return $this->hasMany('path\to\model');
}
}
class CertainOrder extends Model
{
protected $table = "certain_orders";
protected $guarded = [];
public function shoppingCard()
{
return $this->belongsTo('App\path\to\model', 'sepet_id');
//sepet_id is a foreign key.
}
}
class ShoppingCardProduct extends Model
{
use SoftDeletes;
protected $table = "shopping_card_product";
protected $fillable = ['id', 'sepet_id', 'urun_id','quantity','price','status','created_at','updated_at','deleted_at'];
public function ShoppingCard()
{
return $this->belongsTo('App\ShoppingCard');
}
}
and make the call this way
public function orderdetail($id)
{ //certainorder model access to 'ShoppingCard'model from below
$orderDetails = ShoppingCard::with('CertainOrder, ShoppingCardProduct')
->where('id' , $id)->firstorFail();
return view('orderdetails', compact ('orderDetails'));
}
I have worked a lot with Laravel and never got the following error:
Call to a member function getQuery() on null at /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php line 558.
I'm trying to get a record with all the relationships specified. The code that is causing that error is the following:
$id = 7;
$compra = Compra::where('id', $id)
->with(['certificado',
'certificado.duracionServicios',
'certificado.duracionServicios.servicio',
'certificado.duracionServicios.servicio.traducciones' => function($query){
$query->whereHas('idiomas', function($q){
$q->where('codigo_region', 'es_MX');
});
},
'user'])
->first();
If I take out the first() method, I can print the object instance of Builder, but when I try to use it or even use get(), that exception is thrown. Laravel version I'm using is 5.5.
Model Compra
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class Compra extends Model
{
protected $table = 'compras';
protected $fillable = ['folio',
'fecha_compra',
'subtotal',
'total',
'user_id',
'direccion_id',
];
protected $dates = ['created_at', 'updated_at'];
/**
* Get the value of the model's route key.
*
* #return mixed
*/
public function getRouteKey()
{
$hashids = new \Hashids\Hashids(config('app.name'), 5);
return $hashids->encode($this->getKey());
}
public function certificado(){
$this->hasOne('App\Models\Sitio\Certificado', 'compra_id');
}
public function user(){
return $this->belongsTo('App\User', 'user_id');
}
}
Model Certificado
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class Certificado extends Model
{
protected $table = 'certificados';
protected $fillable = ['fecha_servicio',
'hora_servicio',
'compra_id',
];
protected $dates = ['created_at', 'updated_at'];
public function compra(){
return $this->belongsTo('App\Models\Sitio\Compra', 'compra_id');
}
public function duracionServicios(){
return $this->belongsToMany('App\Models\Sitio\DuracionServicio', 'certificados_duracion_servicios', 'certificado_id', 'duracion_id');
}
}
Model DuracionServicio
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class DuracionServicio extends Model
{
protected $table = 'duracion_servicios';
protected $fillable = ['costo',
'servicio_id',
];
protected $dates = ['created_at', 'updated_at'];
public function certificados(){
return $this->belongsToMany('App\Http\Models\Sitio\Certificado', 'certificados_duracion_servicios', 'duracion_id', 'certificado_id');
}
public function servicio(){
return $this->belongsTo('App\Models\Sitio\Servicio', 'servicio_id');
}
public function traducciones(){
return $this->hasMany('App\Models\Sitio\DuracionServicioTraduccion', 'duracion_id');
}
}
Model Servicio
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class Servicio extends Model
{
protected $table = 'servicios';
protected $fillable = ['seccion_id'];
protected $dates = ['created_at', 'updated_at'];
public function traducciones(){
return $this->hasMany('App\Models\Sitio\ServicioTraduccion', 'servicio_id');
}
public function duraciones(){
return $this->hasMany('App\Models\Sitio\DuracionServicio', 'servicio_id');
}
}
Model ServicioTraduccion
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class ServicioTraduccion extends Model
{
protected $table = 'servicios_traducciones';
protected $fillable = ['nombre',
'descripcion',
'contenido',
'idioma_id',
'servicio_id',
];
protected $dates = ['created_at', 'updated_at'];
public function servicio(){
return $this->belongsTo('App\Models\Sitio\Servicio', 'servicio_id');
}
public function idioma(){
return $this->belongsTo('App\Models\Sitio\Idioma', 'idioma_id');
}
}
Model Idioma
namespace App\Models\Sitio;
use Illuminate\Database\Eloquent\Model;
class Idioma extends Model
{
protected $table = 'servicios_traducciones';
protected $fillable = ['nombre',
'codigo_region',
];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
public function servicios(){
return $this->hasMany('App\Models\Sitio\ServicioTraduccion', 'idioma_id');
}
public function duraciones(){
return $this->hasMany('App\Models\Sitio\DuracionServicioTraduccion', 'idioma_id');
}
}
Ok, so the problem is in your Compra model.
You defined relationship like this:
public function certificado()
{
$this->hasOne('App\Models\Sitio\Certificado', 'compra_id');
}
You forgot to add return. It should be:
public function certificado()
{
return $this->hasOne('App\Models\Sitio\Certificado', 'compra_id');
}
You can't call get_query() on a ->first().
->first() will return the first result of your query, and so execute the SQL query (after the first() you get a null result if no result, or your query result object). You should be able to use get_query() or get() if you remove the first() as you'll have an eloquent query instance, not a result object or collection.
You need to build up a query here by calling the query() method first.
$id = 7;
$compra = Compra::query()->where('id', $id)
->with(['certificado',
'certificado.duracionServicios',
'certificado.duracionServicios.servicio',
'certificado.duracionServicios.servicio.traducciones' => function($query){
$query->whereHas('idiomas', function($q){
$q->where('codigo_region', 'es_MX');
});
},
'user'])
->get();
or you can use ->first();
I'm using laravel 5.4, have two models ParentAccount and ChildAccount,
A parent has many childs
Parent
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ParentAccount extends Model
{
//
public $timestamps = false;
protected $table = 'parent_accounts';
protected $fillable = [
'name', 'account_id'
];
public function childs()
{
return $this->hasMany('App\ChildAccount','account_id', 'parent_id');
}
}
child
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ChildAccount extends Model
{
//
public $timestamps = false;
protected $table = 'child_accounts';
protected $fillable = [
'name', 'account_id','parent_id'
];
}
When i use echo ParentAccount::find(1)->childs();
i get an error Call to a member function childs() on null although all parents have children
Note: child has parent_id where it's the account_id in the parent
in parent model
public function childs(){
return $this->hasMany(ChildAccount::class, 'parent_id' , 'account_id');
}
in child model
public function parent(){
return $this->belongsTo(ParentAccount::class, 'parent_id' , 'account_id');
Edited Code
public function childs()
{
return $this->hasMany('App\ChildAccount', 'parent_id','account_id');
}
The relation function must be in the format
public function post()
{
return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
}
First you have to add the primaryKey property then change the relation parameters and add the revers relation to the ChildAccount :
ParentAccount :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ParentAccount extends Model
{
protected $primaryKey = 'account_id';
public $timestamps = false;
protected $table = 'parent_accounts';
protected $fillable = [
'name', 'account_id'
];
public function childs()
{
// 'foreign_key', 'local_key'
return $this->hasMany('App\ChildAccount', 'parent_id', 'account_id');
}
}
ChildAccount :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ChildAccount extends Model
{
protected $primaryKey = 'account_id';
public $timestamps = false;
protected $table = 'child_accounts';
protected $fillable = [
'name', 'account_id','parent_id'
];
public function parent() {
// foreign_key, 'other_key'
return $this->belongsTo('App\ParentAccount', 'parent_id', 'account_id');
}
}
With doing that you can get the childs :
ParentAccount::find(1)->childs;
You got Call to a member function childs() on null because ParentAccount::find(1) return null. Make sure you have ParentAccount with id=1 in your DB.
You need to change keys order like this:
public function childs()
{
return $this->hasMany('App\ChildAccount', 'parent_id', 'account_id');
}
Summary
I am receiving the following error when trying to call the relationship:
Object of class Illuminate\Database\Eloquent\Relations\BelongsToMany
could not be converted to string
My setup is very basic, and consists of two models, User and Role.
User Model [User.php]
<?php
use Illuminate\Auth\UserInterface;
class User extends Eloquent implements UserInterface {
protected $table = 'users';
protected $hidden = array('password');
protected $fillable = array('id', 'username', 'password');
public function getAuthIdentifier() {
return $this->getKey();
}
public function getAuthPassword() {
return $this->password;
}
}
Role Model [Role.php]
<?php
class Role extends Eloquent {
protected $table = "roles";
protected $fillable = array(
'id',
'code',
'name'
);
public function foo() {
return $this->belongsToMany('User', 'map_role_user', 'role_id', 'user_id');
}
}
And finally I'm calling the method foo in the routes file, example:
Route::get('role', function() {
return Role::find(1)->foo();
});
From
https://laravel.com/docs/5.3/eloquent-relationships or https://laravel.com/docs/4.2/eloquent#relationships
If a collection is cast to a string, it will be returned as JSON:
<?php
$roles = (string) User::find(1)->roles;
If you dont want to add further constraints to the query then you have to use dynamic properties concept. So,
$user = App\User::find(1);
foreach ($user->posts as $post) {
//
}
If you want to add more constraints then do this
App\User::find(1)->posts()->where('title', 'LIKE', '%Best%')->get()