Add values to pivot table laravel - php

When I want to save a reaction to a ticket I've three tables (in laravel):
-Tickets
-Reaction
-Reaction_Tickets (pivot table)
When I want to save a reaction I do it like this:
public function addReaction(Request $request, $slug)
{
$ticket = Ticket::whereSlug($slug)->firstOrFail();
$reaction = new reactions(array(
'user_id' => Auth::user()->id,
'content' => $request->get('content')
));
return redirect('/ticket/'.$slug)->with('Reactie is toegevoegd.');
}
But now of course it's not added to the pivot table. And I can't add it because I don't have a model of it. What's the right way of doing this?
EDIT:
-Tickets
public function reactions()
{
return $this->belongsToMany('App\reactions');
}
-Reactions
public function tickets()
{
return $this->hasOne('App\tickets');
}

From the Laravel documentation, you need to save and attach the Reaction to the Ticket:
$reaction = new reactions(array(
'user_id' => Auth::user()->id,
'content' => $request->get('content')
));
$reaction->save(); // Now has an ID
$tickets->reactions()->attach($reaction->id);
In your Ticket model, you need to have the relationship defined:
class Ticket extends Model {
protected $table = "tickets";
public function reactions(){
return $this->belongsToMany("App\Reaction");
}
}
And you should have the inverse defined on Reaction:
class Reaction extends Model {
protected $table = "reactions";
public function tickets(){
return $this->belongsToMany("App\Ticket");
}
}
If your models are set-up like so, you shouldn't have any issue attaching the new Reaction to your existing Ticket via your pivot table.

Related

Display table data without user auth

I'm studying event message board. I can display table data by every Users own post. however I would like to display All post too. I wrote this as $tasksall but it didn't work. Could someone teach me what is wrong?
AController.php
public function index()
{
$tasks = Auth::user()
->tasks()
->orderBy('is_complete')
->orderByDesc('created_at')
->paginate(5);
$tasksall =
->tasks()
->orderBy('is_complete')
->orderByDesc('created_at')
->paginate(5);
return view('tasks', [
'tasks' => $tasks, 'tasksall' => $tasksall
]);
}
Task.php (model)
class Task extends Model
{
protected $casts = [
'is_complete' => 'boolean',
];
protected $fillable = [
'title',
'is_complete',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
AController.php I add this code
public function person()
{
return $this->belongsTo('App\Models\Task');
}
public function getData()
{
return $this->id . ':'/ $this->person->name.')';
}
index.blade.php I add this code
{{ $task2->getData() }}
You can just write a query to get all the task using eloquent to get all the tasks.
$tasksall = Task::all();
Have a look at this link.
Also for you case I think the problem is you are getting task from the User model so you $task will contain only task related to that particular user as you have a belongsTo relation of task with user.
For Your case to get name of User from task.
//Task model
class Task {
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
Then you can query like this in your controller.
$task = Task::find($id);
$name = $task->user->name;

Laravel hasMany save

I've two tables to save data to. One of them has foreign key so that I have one-to-many relationship. However, I don't understand how to save data into two table simultaneously. I have one query which contains data for one table and for another that should be attached to first one.
That is the main model
class Site extends Model
{
protected $fillable = ['path', 'site_link'];
public $timestamps = false;
public function features() {
return $this->hasMany('App\SiteFeature');
}
}
And this is the sub-model
class SiteFeature extends Model
{
protected $fillable = ['feature', 'site_id'];
public $timestamps = false;
}
Right now my controller looks like this
class SiteController extends BaseController
{
public function index()
{
return Site::all();
}
public function show(Site $id)
{
return $this->response->item($id, new SiteTransformer);
}
public function store(Request $request)
{
$site = Site::create($request->all());
return response()->json($site, 201);
}
I know that it would save it as one piece of data. And I ask you for help me to split data into two tables. In docs I've found the way to store with relationship to an existing model in DB, however I don't have that model at the moment of creation.
Solved that way
public function store(Request $request)
{
$site = Site::create([
"path" => $request->path,
"site_link" => $request->link,
]);
foreach ($request->features as $feature) {
$site->features()->save(new SiteFeature(["feature" => $feature]));
}
return response()->json($site, 201);
}
There are certain things you have to make sure of.
First: In your SiteFeature-Model the inverse relation to the Site-Models seems to be missing.
There should be a function like:
public function site()
{
return $this->belongsTo('App\Site');
}
See Laravel 5.6 - Eloquent Relationships, One-to-Many for this.
If however you have a relationship where (n) Sites can be related to (n) SiteFeatures, your relations and inverse relations have to be different.
(And there will also have to be a pivot table, in which you can store the n-to-n relation)
See Laravel 5.6 - Eloquent Relationships, Many-to-Many in that case.
Since your Question does not describe what is received with $request, here's what you should consider:
Validate your inputs. This will make sure you don't save garbage to your database
Check if you already have some part of the data-set you want to save, then save in two steps:
First step:
$site = Site::firstOrCreate(['path' => $request['input_name_for_path'],
'site_link' => $request['input_name_for_site_link'],
]);
This will give you a proper Site-Model saved to the database.
(Note, that this shows how you manually assign values to the fillable fields defined in the model in case you have different input field names)
Now you can go on an save the SiteFeature-Model connected to it:
$feature = SiteFeature::firstOrCreate('feature' => $request['input_name_for_feature');
$site->features()->attach($feature->id);
This should do the trick saving both, a new (or old) Site and a related SiteFeature to your database.
If I misunderstood the question, feel free to add information and I will update.
It's the correct way to save data using hasMany relationship without creating a new object of lookup model.
// inside controller
public function store(Request $request)
{
$student = Student::create([
"name" => $request->get('name'),
"email" => $request->get('email'),
]);
foreach ($request->subjects as $subject) {
$student->subjects()->create(["title" => $subject['title']);
}
return response()->json($student, 201);
}
// inside User model
public function subjects()
{
return $this->hasMany('App\Models\Subject');
}

Laravel - Eloquent attach() not working for models

TL;DR
Trying to get three models to interact using eloquent for a rest api.
User - belongsToMany(pulls)
Pull - belongsToMany(user) && belongsToMany(boxes)
Box - belongsToMany(pulls)
The pull_user table is working perfectly, I can just attach a user after I save a pull. Saving a box works fine but the attach doesn't work/enter anything into the pivot table (I get no errors though).
The Problem
I can't get a pivot table that associates two of my models together to attach() after a save. I have the three models listed above, the pivot is working for pull_user but not for pull_box even though the save for box is working perfectly. I am able to save a box without an error but the association just never occurs (no error).
The Code
pull_box.php
class PullBox extends Migration
{
public function up()
{
Schema::create('pull_box', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('pull_id');
$table->integer('box_id');
});
}
public function down()
{
Schema::dropIfExists('pull_box');
}
}
Pull.php
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box');
}
}
Box.php
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull');
}
}
BoxController.php
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
...
]);
$user_id = $request->input('user_id');
...
$box = new Box([
'user_id' => $user_id,
...
]);
$pull = Pull::whereId($pull_id)->first();
if($box->save()){
$pull->boxes()->attach($box->id);
$box->view_box = [
'href' => 'api/v1/box/' . $box->id,
'method' => 'GET'
];
$message = [
'msg' => 'Box created',
'box' => $box,
'pull' => $pull_id
];
return response()->json($message, 201);
}
$response = [
'msg' => 'Box creation error, contact supervisor',
];
return response()->json($response, 404);
}
The Solution
I need to know how I can get this association working. I am going to need to add a new layer in under the pull for Item, but I don't want to move one before I solve this. I think that my problem has to stem from a syntactical/logical error on my part but I can't see it. There are a bunch of questions on SO that are very close to giving me a solution, but after reading them I wasn't able to solve my problem.
Any help is appreciated.
Try renaming your pull_box table to box_pull, pivot tables on laravel must be in alphabetical order. If you want to use custom name on pivot table you have to extends your pivot, for example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class PullBox extends Pivot
{
protected $table = 'pull_box';
}
And your many to many relationships:
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box')->using('App\PullBox');
}
}
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull')->using('App\PullBox');
}
}

laravel eloquent: many to many relations

I would like to add some items in my db table pivot using eloquent ->attach but i don' t understand why it don't work:
I have 2 models (Salade=>(table 'salades' in DB) and Ingredient=>(table 'ingredients' in DB),
the pivot table is ingredient_salade( 3columns : id, ingredient_id,salade_id).
My Models:
class Ingredient extends Model
{
protected $table = 'ingredients';
protected $fillable = ['nom'];
public function Salades()
{
return $this->belongsToMany('App\Salade');
}
}
class Salade extends Model
{
protected $table = 'salades';
protected $fillable = ['nom','prix'];
public function ingredients()
{
return $this->belongsToMany('App\Ingredient');
}
}
SaladeController#Store
public function store(Request $request)
{
$this->validate($request, [
'nom' => 'required',
'prix' => 'required' ]);
$salade = $request->only(['nom', 'prix']);
// insert new salade in DB
$lanouvelleSalade = \App\Salade::create($salade);
//insert relation in pivot table
$lanouvelleSalade->ingredients()->attach([21,22,23]);
return redirect('salade')->withOk("Le Salade " . $request->input('name') . " a été modifié.");
}
the tables:
image of the tables
the new salade is insert in table salades but the relation in Pivot is not insert. Why?
change:
$lanouvelleSalade->ingredients()->attach([21,22,23]);
to:
$lanouvelleSalade->ingredients()->sync([21,22,23]);
replace your relation codes with this codes and check it:
Ingredient Class:
public function Salades()
{
return $this->belongsToMany('App\Salade','ingredient_salade','ingredient_id','salade_id');
}
And Salade Class:
public function ingredients()
{
return $this->belongsToMany('App\Ingredient','ingredient_salade','salade_id','ingredient_id');
}
let me know if you have any error

working on many to many table and more attributes are required in third table

i am trying to save data in third table in many to many relation but
data is not saving
user model
public function Jobs()
{
return $this->belongsToMany('App\Models\Job','App\Models\Job_User','user_id','job_id');
}
job model
public function Users()
{
return $this->belongsToMany('App\Models\User','App\Models\Job_User','job_id','user_id');
}
controller for saving data in third table is
public function JobApplied(Request $request){
$applied= new Job_User();
$applied->user_id = Auth::id();
$applied->job_id = $request->job_id;
$applied->cv = $request->cv;
$applied->current_salary = $request->current_salary;
$applied->expected_salary = $request->expected_salary;
$applied->save();
return redirect('searchjobs');
}
code of third table is
class Job_User extends Model
{
protected $fillable = [
'user_id','job_id','cv','current_salary','expected_salary','status',
];
protected $table = 'jobs_users';
}
You're using the many-to-many relation incorrectly. You don't need a model for the intermediate table as Eloquent will handle it for you.
First of all, you need to define the relation in your models in a correct way. The second argument should be the name of the intermediate table, not the model. As you're using the default values for table name and foreign key column names, you can skip them and just do:
public function Jobs()
{
return $this->belongsToMany('App\Models\Job');
}
public function Users()
{
return $this->belongsToMany('App\Models\User');
}
If you want to have additional fields in the intermediate column, you need to define it when you define a relationship using withPivot() method:
public function Jobs()
{
return $this->belongsToMany('App\Models\Job')->withPivot('cv','current_salary','expected_salary','status');
}
public function Users()
{
return $this->belongsToMany('App\Models\User')->withPivot('cv','current_salary','expected_salary','status');
}
Now, if you want to link a Job with a User and set the fields in the intermediate pivot table, you should use save() method on your relation:
$job->users()->save($user, ['cv' => $request->cv, 'current_salary' => $request->current_salary]);
or
$user->jobs()->save($job, ['cv' => $request->cv, 'current_salary' => $request->current_salary]);
Once you have data saved in your database you can retrieve data from intermediate pivot table using the pivot attribute of related model, e.g.:
foreach($user->jobs as $job) {
echo $job->pivot->current_salary;
}
or
foreach($job->users as $user) {
echo $user->pivot->current_salary;
}
Check the docs for more information about handling many-to-many relationship with Eloquent: https://laravel.com/docs/5.1/eloquent-relationships#many-to-many

Categories