Problem relationship many to many on Laravel - laravel

I'm new to Laravel, I'm having this problem:
I have 2 tables, platos and ingredientes, these have a many to many relationship, and for this I use a third table called ingredientes_platos.
To save the relationship many to many I tried with the following:
$platos->ingredientes()->attach($input['ingredientes']);
but it gives the following error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '151-3' for key 'PRIMARY' (SQL: insert into ingredientes_platos (platos_id, ingredientes_id, norma_bruta) values (151, 3, ))
Looking a bit in the documentation, I could solve with sync instead of attach, but this does not solve my problem, because in addition to saving the id's of the relationship I need to save other attributes in the pivot table.
It is important to note that if I try to save this data in a table other than ingredients_platos, I do not get this problem and the data is saved correctly no matter which method I use.
I appreciate your attention, I hope you can help me.
These are the models for the three tables:
Table Platos:
public $table = 'platos';
protected $dates = ['deleted_at'];
public $fillable = [
'Grupo',
'Nombre',
'Procedimiento',
'Cantidad',
'Unidad',
'Precio'
];
/**
* The attributes that should be casted to native types.
*
* #var array
*/
protected $casts = [
'Grupo' => 'integer',
'Nombre' => 'string',
'Procedimiento' => 'string',
'Cantidad' => 'integer',
'Unidad' => 'integer',
'Precio' => 'double'
];
/**
* Validation rules
*
* #var array
*/
public static $rules = [
'Grupo' => 'required',
'Nombre' => 'required'
];
public function ingredientes()
{
return $this->belongsToMany(Ingredientes::class);
}
public function grupo_platos()
{
return $this->hasOne('App\Models\Grupo_Platos', 'id', 'Grupo');
}
}
Table Ingredientes:
public $table = 'ingredientes';
protected $dates = ['deleted_at'];
public $fillable = [
'Grupo',
'Nombre',
'Descripcion',
'Kcal',
'Proteinas',
'Grasas',
'Unidad',
'Precio'
];
/**
* The attributes that should be casted to native types.
*
* #var array
*/
protected $casts = [
'Grupo' => 'integer',
'Nombre' => 'string',
'Descripcion' => 'string',
'Kcal' => 'double',
'Proteinas' => 'double',
'Grasas' => 'double',
'Unidad' => 'integer',
'Precio' => 'double'
];
/**
* Validation rules
*
* #var array
*/
public static $rules = [
'Nombre' => 'required'
];
public function platos()
{
return $this->belongsToMany(Platos::class);
}
}
Table Ingredientes_Platos:
public $table = 'ingredientes_platos';
public $fillable = [
'platos_id',
'ingredientes_id',
'norma_bruta',
'norma_neta',
'unidad_id'
];
public $timestamps = false;
}
Platos Controller:
public function store(CreatePlatosRequest $request)
{
$input = $request->all();
$platos = $this->platosRepository->create($input);
$id = $platos->id;
$ingredientes = $input['ingredientes'];
$norma_b = $input['norma_b'];
$t = sizeof($ingredientes);
$i=0;
for ($i = 0; $i < $t; $i++) {
$pivot = new Ingredientes_Platos;
$pivot->platos_id = $platos['id'];
$pivot->ingredientes_id = $ingredientes[$i];
$pivot->norma_bruta = $norma_b[$i];
$pivot->save();
}
Flash::success('Plato agregado correctamente.');
return redirect(route('platos.index'));
}

If you need one type to "belong" to another type multiple times, and vice versa, then the generic many-to-many relationship probably isn't a good fit for what you're trying to do. Not just because of the primary key constraint, but because you'll have cases in which multiple row results are returned for the relationship, and the many-to-many relationship won't know how to aggregate or group these. You may want to come up with a third type of Model that's something like an "attribute" that has relationships to the other two models and helps you accomplish your goal.

Thank you very much, my problem was solved. It happens that in addition to Laravel, I'm using InfyOM and this was creating a conflict when I was trying to manually add the records to the pivot table, because this line was already responsible for adding the registry to the pivot table: $ dishes = $ this-> dishesRepository-> create ($ input);

// Many to Many relationship in category Model to Post model coding here
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}
}
// Many to Many relationship in Post Model to Category model coding here
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function categories(){
return $this->belongsToMany('App\Category')->withTimestamps();
}
}

Related

Get specific columns having with() function in laravel

Category Model definition is:
class Category extends Model
{
public $implement = ['#RainLab.Translate.Behaviors.TranslatableModel'];
public $translatable = ['name'];
/**
* #var string The database table used by the model.
*/
public $table = 'shop_category';
/**
* #var array Validation rules
*/
public $rules = [
];
public $attachOne = [
'icon' => 'System\Models\File'
];
public $hasMany =[
'shops' => ['ItScholarBd\Api\Models\Shop', 'key' => 'shop_category_id']
];
}
I want to get category with shop. It works fine if I retrieve all columns but if I try to retrieve specific column it is not working. I want to get only the following columns:
id, name of each table. I also apply a condition where Shop.status = 1. I am trying as follows:
$this['categoryWithShop'] = Category::select('id,name')->with(array('shops'=>function($query){
$query->where('status','=',0);
$query->select('id','name');
}))->get();
Any idea?
Try this,
$this['categoryWithShop'] = Category::select('id,name')->with(array('shops'=>function($query){
$query->where('status','=',0);
$query->select('id','name', 'status');
}))->get();
In select query you need to pass that all columns which is needed in query.
try this chaining method and select('id,name') this is wrong you need to fix this as select('id','name')
ref link https://laravel.com/docs/8.x/queries#selects
$this['categoryWithShop'] = Category::select('id','name')->with(['shops' => function ($query) {
$query->select('id', 'name')->where('status', '=', 0);
}])->get();

Indirect modification of overloaded on Laravel - Relationship

I use Laravel 5 and i have 2 tables:
"Link" Table with 7 columns, one of them is "image_id" column.
"Image" Table, in this table i have two column, an "id" and "url".
I want to update my Link database and also it's related image url with single update method.
I have tried this code:
public function update(Request $request, $id)
{
// Validate the data
$link = Link::find($id);
$this->validate($request, array(
'title' => 'required|max:255',
'link' => 'nullable',
'description' => 'required'
));
$link = Link::find($id);
$link->title = $request->input('title');
$link->link = $request->input('link');
$link->description = $request->input('description');
$link->linkImage->url = 'testurl';
$link->save();
Session::flash('success', "Le lien à été correctement mis à jour.");
return redirect()->route('links.index');
}
This is my Link class:
<?php
namespace App\Models\Services;
use Illuminate\Database\Eloquent\Model;
class Link extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'service_rubrique_link';
protected $fillable = ['title','description','ordre','image_id'];
public function linkImage()
{
return $this->belongsTo('App\Models\Storage\Imageup');
}
}
And my Image Class:
<?php
namespace App\Models\Storage;
use Illuminate\Database\Eloquent\Model;
class Imageup extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'image';
protected $fillable = ['id','url'];
public function servlinks()
{
return $this->hasMany('App\Models\Services\Link');
}
}
When i want to save i have this error:
Indirect modification of overloaded property
App\Models\Services\Link::$linkImage has no effect
Do you have any idea of what is wrong with my code ?
Thank you.
As the message says the property is a lazy loaded sub model.
Updating does not makevsense... you should use it as method (query builder) linkimage() and then use for example ->update(['propertyname' => 'value'])
See https://laravel.com/docs/7.x/eloquent-relationships#inserting-and-updating-related-models

Laravel many to many relationship with uuid returns always empty

I use Laravel 5.8 and changed my model's autoincrement id to uuid. Since then I have some trouble with my many-to-many relationship that was defined between 2 of my models Event and User (with pivot table events_users).
The problem :
Now when I request all element that join both table (I have 2 records in my pivot table) I always get an empty array back.
When debugging the sql, I see that the where clause param is not set :
// Generated sql
select `users`.*, `events_users`.`event_id` as `pivot_event_id`, `events_users`.`user_id` as `pivot_user_id`, `events_users`.`created_at` as `pivot_created_at`, `events_users`.`updated_at` as `pivot_updated_at`
from `users`
inner join `events_users` on `users`.`id` = `events_users`.`user_id`
where `events_users`.`event_id` = ?
// Bindings :
Array
(
[0] =>
)
Has someone any clue what I'm missing here ?
Here are the definition of my models :
class Event extends Model
{
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
// here some other model methods, fillable property, etc.
public function users()
{
return $this
->belongsToMany(User::class, 'events_users', 'event_id', 'user_id')
->withTimestamps();
}
}
Same declaration for User model, but with relation
public function events()
{
return $this
->belongsToMany(Event::class, 'events_users', 'user_id', 'event_id')
->withPivot(['created_at', 'updated_at']);
}
Then I retrieve the relations from the service with :
public function getSubscriptions($eventId)
{
$eventId = 'a1b7c5d6-8f86-44f4-f31a-46e32917d5c0'; // for debug purpose only
$event = Event::find($eventId);
foreach ($event->users as $user) {
print_r($user); die; // It never loops here as its length is 0 but should be 2...
}
\DB::listen(function ($query) {
print_r($query->sql);
print_r($query->bindings);
// $query->time
});
$subscriptions = $event
->users()
->get();
die;
return $subscriptions;
}
My DB contains the records
The problem was about another declaration in my models where I list the property.
I've initialized an id property there, which is probably in conflict with the uuid type or I don't know exactly what cause this drama...
Anyway, removing this line let the app work correctly.
/**
* #var array
* Rules used for fields validation
*/
public $rules = array(
'title' => 'required|string|max:255',
'start_date' => 'required|date|date_format:Y-m-d',
'end_date' => 'required|date|date_format:Y-m-d|after_or_equal:start_date',
'location' => 'string|max:254',
'latitude' => 'numeric',
'longitude' => 'numeric'
);
public $id = ""; // This is the line that create the bug... Remove it and it works !
public $title = "";
public $start_date = "";
public $end_date = "";
public $location = "";
public $latitude = "";
public $longitude = "";

Data missing in Carbon on Laravel Many to Many relation

I recently change my database from from MySql to MSSql and I'm having problems with date formats. I changed all models to use $dateFormat = 'Y-m-d H:i:s' and work's fine, but today I'm having problem with a model that have a relation many-to-many with other model.
My database are saving the dates in format Y-m-d H:i:s.000, in this way 2018-08-20 16:01:12.000. I think that eloquent aren't respecting the date format.
I'm using Laravel 5.4 and php 5.6;
Today, I'm getting this error
InvalidArgumentException in Carbon.php line 909:
Data missing
in Carbon.php line 909
at Carbon::createFromFormat('Y-m-d H:i:s.000', '2018-07-19 10:40:21') in Model.php line 3003
The code that are generate the error,
public function getDetailQuiz()
{
$quiz_id = Input::get('quiz_id');
*$quiz = QuizTopic::with('questions.answers')->where('id', $quiz_id)->first();*
foreach ($quiz->questions as $question) {
$answers = [];
$answer_order = 0;
foreach ($question->answers as $i => $answer) {
$answers[] = ['answer' => $answer->description, 'id' => $answer->id, 'action' => 'update'];
if ($question->answer_id == $answer->id) $answer_order = $i;
}
$response['questions'][] = [
'id' => $question->id,
'question' => $question->description,
'correct_answer' => $question->answer_id,
'points' => $question->points,
'answers' => $answers,
'action' => 'update',
'answer_order' => $answer_order,
];
}
$quiz->start_date = Carbon::parse($quiz->start_date)->format('d/m/Y H:i');
$quiz->end_date = Carbon::parse($quiz->end_date)->format('d/m/Y H:i');
$response['quiz'] = $quiz->makeVisible(['award_value', 'type_id', 'start_date', 'end_date'])->toArray();
return response()->json(['result' => $response]);
}
My QuizTopic Model
class QuizTopic extends Model
{
protected $table = 'quiz_topics';
protected $guarded = ['id'];
protected $hidden = [
'created_at',
'updated_at',
'deleted_at',
'created_user_id',
'updated_user_id',
'winner_clerk_id',
'award_value',
'status_id',
'type_id',
'start_date',
'end_date',
'raffle_date',
'fcm_notification_reference',
];
protected $dateFormat = 'Y-m-d H:i';
use SoftDeletes;
public function questions()
{
return $this->belongsToMany('App\Models\QuizQuestion', 'rel_topics_questions', 'topic_id', 'question_id')->withTimestamps();
}
}
My QuizQuestion Model
class QuizQuestion extends Model
{
protected $table = 'quiz_questions';
protected $guarded = ['id'];
protected $hidden = ['created_at', 'updated_at', 'deleted_at','points','pivot','created_user_id','updated_user_id'];
protected $dateFormat = 'Y-m-d H:i:s';
use SoftDeletes;
public function topics()
{
return $this->belongsToMany('App\Models\QuizTopic');
}
public function answers()
{
return $this->belongsToMany('App\Models\QuizAnswer', 'rel_questions_answers', 'question_id', 'answer_id')->withTimestamps();
}
}
From the manual:
By default, timestamps are formatted as 'Y-m-d H:i:s'. If you need to
customize the timestamp format, set the $dateFormat property on your
model. This property determines how date attributes are stored in the
database, as well as their format when the model is serialized to an
array or JSON
(emphasis mine)
Since you're saving your dates as Y-m-d H:i:s.000, you need to set the $dateFormat property in both of your models as such:
protected $dateFormat = 'Y-m-d H:i:s.000';
Change that and try again.

relations issue with laravel

I am trying to make games website, so i have one-to-many relation: one category has many games.
in my db, I have games' table and cats' table.
in the games' table I have a column named as 'cat_game_id' which reffers to the category's id, that the game belongs to.
my 'game' model looks like this
`
class Game extends Model {
protected $fillable = array(
'name',
'slug',
'description',
'instruction',
'url',
'cat_game_id',
'created_at',
'updated_at'
);
/*
* A game belongs to a category
*/
public function cat() {
return $this->belongsTo('App\catGame');
}
}
`
and i have another model called 'catGame':
`class catGame extends \Eloquent {
public $timestamps = false;
protected $fillable = array(
'name',
'location',
'slug'
);
/*
* A category has many games
*/
public function games() {
return $this->hasMany('App\Game');
}
}
`
In my index page I want to show the game's name, and next to it the category's name. so I did:
$view->game = Game::where('slug', '=', $slug)->firstOrFail();
$view->cat_name = $view->game->cat->name;
but I get this error:
Trying to get property of non-object
any ideas please?

Resources