Laravel saving foreign key in another table - php

What is the best approach to save the stream_id as a foreign key inside the junk table
I already created the tables both tables.
Migration:
public function up()
{
Schema::table('junk', function(Blueprint $table)
{
$table->integer('stream_id')->after('id')->unsigned();
});
}
Controller function:
public function create(Request $request)
{
// create junk, junk shall contain the stream id as a foreign key (save in database)
$junk = new Junk();
// stream information data -> the data is saved correctly here
$data = $request->all();
$stream = new Stream();
$stream->fill($data);
if($stream->save())
{
return redirect()->route('stream.new')->with('success', 'saved.');
}
else
{
return redirect()->route('stream.new')->with('error', 'not saved.')->withInput();
}
}
My Junk Model:
public function junk()
{
return $this->belongsTo('Stream', 'junk_id');
}
My Stream Model
public function stream()
{
return $this->belongsTo('Junk', 'stream_id');
}

Do you want to use foreign key contraints? If so, You might take this approach. Here is an example of a location table that has a foreign key to the coordinates:
public function up()
{
Schema::enableForeignKeyConstraints();
Schema::create('location', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->uuid('id');
$table->primary('id');
$table->uuid('coordinate_id')->nullable();
$table->string('address')->nullable();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('zipcode')->nullable();
$table->timestamps();
});
Schema::table('location', function(Blueprint $table){
$table->foreign('coordinate_id')->references('id')->on('coordinate');
});
}
There is no reference to the location on the coordinate table.
You should not be assigning $data = $request->all(); you should be using Validator class to protect yourself from mass assignment issues.
It would also be nice to see your Junk class.

If you have the functions to relacionate the models, you can make this:
$junk = new Junk();
$junk->stream()->associate($request->all());
In the relationship:
One to Many, uses the associate() method
Many To Many, uses the attach() method
For more information about the relations in Laravel (Eloquent ORM)
https://laravel.com/docs/5.4/eloquent-relationships#inserting-and-updating-related-models

Related

In Eloquent how would I check if a table row is associated with another?

Before I get into what my issue is, here is my setup. (FYI I am stuck using Laravel 7.4 at the moment so SOS):
Applications Table
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Reports Table
public function up()
{
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
ApplicationReports Table (I know the naming convention is off, but this is how I have to do it for code base)
public function up()
{
Schema::create('applicationReports', function (Blueprint $table) {
$table->unsignedInteger('application_id')->nullable(false);
$table->unsignedInteger('report_id')->nullable(false);
});
}
Here is an example of the ApplicationReports table
application_id
report_id
200
2
Then I have a many to many relationship setup between the Applications and Reports tables like so:
Applications Model
public function reports() {
return $this->belongsToMany(Report::class, 'applicationReports');
}
Reports Model
public function applications() {
return $this->belongsToMany(Application::class, 'applicationReports');
}
In the ReportsController I have a method that will pull all the reports that are in the reports table and then return them, that method looks a little bit like the code below (pseudo coded some of it). But what I am trying to do is only add reports that are associated with applications to the list. When I try the code below doing $report->applications->has($report->id) its returning false and I can't for the life of me figure it out.
public function getReports() {
//Pseudo codeish right here, sorry.
$reports = gets all reports->with(['applications'])->orderBy('name')->get();
$reportsList = [];
foreach ($reports as $report) {
if ($report->applications->has($report->id)) {
$reportsList[] = $report;
}
}
return $reportList;
}
If I dd $report->applications the relationship is there and I can see it under #relations -> #attributes, any help would be appreciated!
The has function is very straight forward.
You can query your reports that only contains applications by doing:
$reports = Report::with('applications')->has('applications')->get();
return $reports;
in other way you can also use whereHas this will accepts Query Builder that you can pass through.
For example:
$reports = Report::with('applications')
->whereHas('applications', function(Builder $query) {
$query->orderBy('created_at');
})->get();
return $reports;

ERROR : how to get information to foreign key laravel 8

I cannot retrieve the username from the foreign key, please help me.
The user table contains a name field I think with the foreign key I could retrieve that. But it does not work.
My migration table
public function up()
{
Schema::create('bookings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->integer('doctor_id');
$table->unsignedBigInteger('campagne_id');
$table->string('time');
$table->integer('status')->default(0);
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('campagne_id')->references('id')->on('campagne')->onDelete('cascade');
});
}
My booking Model
public function utilisateur()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function Campagne()
{
return $this->belongsTo(Campagne::class, 'campagne_id', 'id');
}
}
my controller
public function liste()
{
$bookings = DB::table('bookings')->paginate(6);
return view('listeAppointement', compact('bookings', 'doctors'));
}
My erreur enter image description here
i dont know happen. Thanks for advance.
Your setup is good to go, Did you verified that all reference 'user_id' from table bookings exist on users table? It happens sometimes when relation not find required field with foreign key.

laravel nova - how to make a self referential model with restriction

I have a laravel model based on the following table:
public function up()
{
Schema::create('things', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('label');
$table->foreignId('user_id')->nullable()->constrained('users');
});
There is also a pivot table that makes this a many-to-many self-referential model.
public function up()
{
Schema::create('thing_thing', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('message')->nullable();
$table->unsignedBigInteger('parent_id')->nullable();
$table->unsignedBigInteger('child_id')->nullable();
$table->unique(['parent_id', 'child_id']);
$table->foreign('parent_id')->references('id')->on('things')->onDelete('cascade');
$table->foreign('child_id')->references('id')->on('things')->onDelete('cascade');
});
}
When I create a Nova resource linked to this model, I would like to restrict the attaching of a thing to itself. So a thing with id = 1, for example, would not show up in the selector for attachments for the thing with id = 1. Here's my Nova resource:
public function fields(Request $request)
{
return [
ID::make(__('ID'), 'id')->sortable(),
Text::make('label'),
ID::make('user_id')->hideWhenUpdating()->hideWhenCreating(),
BelongsToMany::make('Trees', 'trees'),
BelongsToMany::make('Things', 'childOf'),
BelongsToMany::make('Things', 'parentOf')
];
}
You can solve this through the App\Nova\Ressource's relatableQuery method. Simply override the method in your nova resource:
class Thing extends Resource {
// ...
public static function relatableQuery(NovaRequest $request, $query)
{
// Make sure you only apply the filter to the things-things relatable query
if( $request->route('resource') === 'things' ) {
$currentId = $request->route('resourceId');
$query->where('id', '!=', $currentId);
}
return $query
}
}
You can find the docs here
In addition, you might want to make the column-combination of parent_id and child_id unique in your migration to further ensure uniqueness.

Laravel related model attributes are empty?

I'm trying to give ability on user to see his orders. I have created relationships but when i (dd) the result of the function, the related model attributes are empty.
I don't know what is wrong.
Here is my buyer function
//Buyer Orders
public function myOrders()
{
$user = User::find(auth()->user()->id);
$user = $user->products();
dd($user);// related model attributes shows empty
return view('myOrders')->with(compact('user'));
}
and here is my user
public function products()
{
return $this->hasMany(Products_model::class);
}
public function orders()
{
return $this->hasMany(Order::class);
}
public function allOrdersBuyerSeller()
{
return $this->hasMany(OrderProduct::class);
}
products_model
public function orders()
{
return $this->belongsToMany('App\Order', 'order_product');
}
public function user()
{
return $this->belongsTo('App\User');
}
User Migration
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Product Migration
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('pro_name');
$table->integer('pro_price');
$table->text('pro_info');
$table->integer('stock');
$table->integer('category_id');
$table->string('image')->nullable();
$table->timestamps();
$table->bigInteger('seller_id')->unsigned()->index();
$table->foreign('seller_id')->references('id')->on('users')->onDelete('cascade');
});
}
I would like to see the attributes of the table like price, name, info, img and etc.
Barring the comments about your code, the reason you're not seeing the result of your products query is that you're not passing a closure to the query.
$user = $user->products();
Currently, $user is a QueryBuilder instance. Until you use a closure, like first(), get(), paginate(), etc, you won't be able to see the rows. Modify your code to the following:
$products = $user->products;
// OR
$products = $user->products()->get();
If you omit the (), it will load the relationship using products()->get(), unless already loaded.
Edit: You likely need to include foreign keys to your relationships as the Model name won't match:
User.php
public function products(){
return $this->hasMany(Product_model::class, "seller_id", "id");
}
Probably best to review the contents of the documentation for Relationships; https://laravel.com/docs/5.8/eloquent-relationships. There's a lot of incorrect practices going on with your naming, querying, etc.

Delete all posts related to a user in laravel

this is my posts table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->integer('category_id')->unsigned()->index();
$table->integer('photo_id')->default(0)->unsigned()->index();
$table->string('title');
$table->text('body');
$table->timestamps();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
});
}
this is my users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->index()->unsigned()->nullable();
$table->integer('photo_id')->index()->default(0);
$table->boolean('is_active')->default(0);
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
these are the relations
public function posts() {
return $this->hasMany('App\Post');
}
public function user() {
return $this->belongsTo('App\User');
}
Delete code of the user
public function destroy($id)
{
$user = User::findOrFail($id);
if($user->photo_id !== 0) {
unlink(public_path() . $user->photo->path);
}
$user->delete();
Session::flash('deleted_user', 'The user has been deleted.');
return redirect('/admin/users');
}
Delete code of the post
public function destroy($id)
{
$post = Post::findOrFail($id);
if($post->photo_id !== 0) {
unlink(public_path() . $post->photo->path);
}
$post->delete();
return redirect('/admin/posts');
}
I am trying to delete all the posts related to a user when I delete a user.
For that, I am using foreign reference constraint in posts table as shown above
But it is not working when I delete the user. The posts are still there.
I dont know what I am doing wrong
This problem occurs most probably because the default table engine in your MySQL instance is set to MyISAM which doesn't support foreign keys. Trying to work with foreign keys on a MyISAM table would definitely not be a bug in Laravel. Although it would be nice if the Schema Builder could automatically set the engine to InnoDB if foreign keys are used.
so, use this line in your schema
$table->engine = 'InnoDB';
or alter the table with
ALTER TABLE table_name ENGINE=InnoDB;
May be help you.
Create you custom method like function destroyAllByUser()
and put the code like
DB::table('posts')->where('user_id', '=', 1)->delete();
I hope it may help
Delete user;
public function destroy($id)
{
$user = User::findOrFail($id);
if($user->photo_id !== 0) {
unlink(public_path() . $user->photo->path);
}
$user->posts->delete();
$user->delete();
Session::flash('deleted_user', 'The user has been deleted.');
return redirect('/admin/users');
}
A alternative way to solve that is to configure database.php file under laravel-project\config folder to work on InnoDB engine.
'mysql' => [
...
'engine' => 'InnoDB'
]
Now you don't need to worry when you using foreign keys...
REMEMBER - If you didn't configured this before you create your tables you should remigrate again.

Categories