Laravel 5.5: Getting id after insert - php

I have a model hotel.php to insert hotel data.insert data using create() but it dosen't return id, the returning collection hasn't id field!
Controller.php
/** "/user/2/create" */
public function store(User $user, HotelRequest $request)
{
$slug = (new hotel)->uniqueSlug( $request->name );
$request->merge([
'cat_id' => 1,
'slug' => $slug,
'created_by' => auth()->user()->id,
]);
$hotel = $user->hotels()->create( $request->all() );
dd($hotel);
................
hotel.php (model)
namespace App;
use Illuminate\Http\UploadedFile;
use Illuminate\Database\Eloquent\Model;
class hotel extends Model
{
protected $fillable = ['name', 'description','address','street','city','email',
'phone','web','cat_id','slug','created_by'];
protected $primaryKey = 'slug';
/**
unique slugs genarating
*/
protected $slug_guards = ['create','room'];
public $incrementing = false;
User.php (model)
public function hotels( )
{
return $this->hasmany('App\Hotel');
}
and the final result
It dosen't have id attribute. I need id to upload image!
NB: I changed that primarykey to default 'id' but no change in result.
Create_hotels... migration
public function up()
{
Schema::create('hotels', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('created_by');
$table->integer('cat_id');
$table->string('name');

Your hotel model set the primary key as the slug :
protected $primaryKey = 'slug';
What i usually do, is for all my migrations, i set an autoincrements like following :
$table->increments('id');
this way laravel handles everything for you. Each create, update or whatever method handle the id of your items.
With this, you can then return the id of a stored data this way :
$id = create($data)->id;
where $data is your model with new datas. $id should now contain the id value of the newest stored model datas.

You have to change the Hotel model (or remove the whole line):
public $incrementing = true;

You are dumping the data you just inserted into the db which does not contain a id field.
create a show method in your Controller class as follows
public function show(User $user){
dd($user)
}
with a route as follows:
Route::get('user/{user}', 'Controller#show')

In hotel.php before the protected $fillable declaration try adding
protected $guarded = [
'id',
];
In your controllers store() method just after $slug = (new hotel)->uniqueSlug( $request->name );
try adding a $slug->save(); then returned slug should have an ID returned with it.
and/or possible the same similar strategy after line
$hotel = $user->hotels()->create( $request->all() );
by adding $hotel->save();

I changed the primarykey to default id and $incrementing = true; now its returning id of the created data. I changed whole methodes in Controller

Related

Laravel hasOne() Function Using $this when not in object context

I have 2 models named AdminContent, AdminCategory. I have content_category_id in my admin_contents table. I have category_id and category_name in my admin_categories table. I linked category_id with content_category_id foreign.
I am using the hasOne() function in my Admin Content model. But I get the error Using $this when not in object context!
My main goal is to get content_category_id value from admin_categories table name column
Migrations
// Admin Categories Migration
Schema::create( 'admin_categories', function(Blueprint $table) {
$table->bigIncrements('ctgry_id')->unique();
$table->string('category_name', 50)->unique();
$table->timestamps();
});
// Admin Contents Migration
Schema::create('admin_contents', function (Blueprint $table) {
$table->bigIncrements('cntnt_id')->unique();
$table->string('content_title');
$table->text('content_content');
$table->string('content_slug');
$table->bigInteger('content_category_id');
$table->foreign('content_category_id')->references('ctgry_id')->on('admin_categories');
$table->string('content_status');
$table->string('create_user');
$table->string('content_tags');
$table->string('content_excerpt');
$table->dateTime('posted_at');
$table->timestamps();
});
Models
// AdminContent Model
protected $table = "admin_contents";
protected $fillable = [
'content_title', 'content_content',
'content_category_id', 'content_status', 'create_user','content_tags',
'content_excerpt',
'created_at', 'updated_at'
];
protected $guards = [
'cntnt_id',
];
public function setCategoryName()
{
return $this->hasOne(AdminCategory::class);
}
When I want to access with $this->hasOne(AdminCategory::class) I get this error!
First: relationships in Laravel are based in standardize models, using 'id' as column name for ids. If you are using another name for firstKey, you should add it to relationship definition, as stated in documentation. I mean, your relationship should not work because Eloquent doesn't know which are your tables first keys.
Second: when you define a relationship you should call id from your model. So how are you accessing to $this->hasOne(AdminCategory::class)?
It should be something like AdminContent::with('setCategoryName')
Maybe showing some code from your controller we can give you a more accurate reply.
What I want is this,
I get the blog content with query and print it. But I am printing the content_category_id value as the id value in category table. What I need to do is get the content_category_id and the id value in the category table, the category name linked to that id. Thanks in advance for your help.
Admin Content Model
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class AdminContent extends Model
{
use HasFactory;
protected $table = "admin_contents";
protected $primaryKey = 'cntnt_id';
protected $fillable = [
'content_title', 'content_content',
'content_category_id', 'content_status', 'create_user','content_tags',
'content_excerpt',
'created_at', 'updated_at'
];
protected $guards = [
'cntnt_id',
];
public function _all()
{
return self::all();
}
public static function setCategoryName()
{
return $this->hasOne(AdminCategory::class, 'content_category_id', 'ctgry_id');
}
}
Admin Category Model
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AdminCategory extends Model
{
use HasFactory;
protected $table = 'admin_categories';
protected $primaryKey = 'ctgry_id';
protected $fillable = [
'category_name', 'updated_at'
];
protected $quards = [
'ctgry_id', 'created_at'
];
}
Post Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Admin\AdminContent;
class PostController extends Controller
{
public function index()
{
return view('frontend.blog');
}
public function getCategoryName()
{
return AdminContent::find(1)->setCategoryName;
}
}
MySQL Tables
https://www.hizliresim.com/2z0337a

How can I use soft deleted with relation

I use eloquent with soft delete .I'm getting error because of my query still select data that already use softdelete here is my model
User Model
class User extends Authenticatable
{
use Notifiable, HasRoles, SoftDeletes;
protected $guard_name = 'web';
protected $fillable = [
'username', 'password'
];
protected $dates = ['deleted_at'];
}
for example I've 100 user and I deleted 1 user with softdelete . then I try to
$a = User::all();
dd($a);
I get 99 user . It works! but after I use it relation It doest work here what I do
This is my Parent table and Model
table
|id|user_id|parent_id|
Note : user_id and parent_id are FK in user.id table
class Parent extends Model
{
protected $table = 'parent';
public function user()
{
return $this->belongsTo('App\User');
}
}
$getParent = Parent::with('user')->get();
when I dd($getParent); why I still get null data from user_id that I already use soft deleted ?
UPDATE model User : after I put whereNull I still getting user that I alredy soft deleted
public function user()
{
return $this->belongsTo('App\User')->whereNull('users.deleted_at');
}
https://laravel.com/docs/5.7/eloquent#querying-soft-deleted-models
...
public function customerAddress()
{
return $this->hasOne(Addresses::class, "id", "id_address")->withTrashed();
}
...
Ok, here's what I think is going on...
With soft delete the ondelete event doesn't work (meaning that related models is not deleted). I'm not sure if that changed in later versions of Laravel, but I don't think so. Also deleting User would still not affect the parent model, since you haven't defined the relationship between User and Parent (in the User model), only between Parent and User.
Try defining the relationship in User and then override the boot() function, that sits in the Model class. (This is untested code, but something like this should do the job)
class User extends Authenticatable
{
use Notifiable, HasRoles, SoftDeletes;
protected $guard_name = 'web';
protected $fillable = [
'username', 'password'
];
protected $dates = ['deleted_at'];
// Override Model boot function
protected static function boot()
{
parent::boot();
static::deleting(function ($users) {
foreach ($users->parents()->get() as $parent) {
$parent->delete();
}
});
}
// Define relationship with parent model
public function parents()
{
$this->hasMany('App\Parent');
}
}
You can put a constraint on the Eager Load:
public function groups()
{
return $this
->belongsToMany('Group')
->whereNull('group_user.deleted_at') // Table `group_user` has column `deleted_at`
->withTimestamps(); // Table `group_user` has columns: `created_at`, `updated_at`
}
Instead of HARD deleting the relationship using:
User::find(1)->groups()->detach();
You should use something like this to SOFT delete instead:
DB::table('group_user')
->where('user_id', $user_id)
->where('group_id', $group_id)
->update(array('deleted_at' => DB::raw('NOW()')));

Eloquent Many to Many attach() is passing a null model ID

I am developing an application using Laravel and Eloquent ORM, it uses a database filled with event information.
I have successfully implemented attach() in the relevant controllers for both my user and role models.
My Event model can have many Links. A Link can have Many events.
My problem is that the attach() is not supplying the ID of the object it is being called on, instead it supplies null and I receive the following error message:
SQLSTATE[23000]: Integrity constraint violation:
1048 Column 'link_id'
cannot be null (SQL: insert into 'event_link' ('created_at', 'event_id',
'link_id', 'updated_at') values (2018-06-09 11:27:15, 2, , 2018-06-09 11:27:15))
I've triple checked my models and database structure.
I can't even imagine how this error could occur since the id lacking in the SQL query is the id of the object that the attach() method is actually being called on. If I use sync($eventID, false) instead of attach(), the result is the same.
Event table:
Link table:
Event_Link table:
The following is the problematic method in the controller responsible for storing the record and creating an entry in the event_link weak entity.
The $link object is created successfully if the attach() line is commented out, a JSON representation of a link is returned which confirms this (but it lacks the 'id' field).
public function store(StoreLink $request) {
$link = Link::create([
'title' => $request->title,
'url' => $request->url,
]);
if ($request['eventId']) {
// $request->eventId is passed successfully, $link id is not passed.
$link->events()->attach($request->eventId);
}
return response()->json($link, 201);
}
Link Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Link extends Model
{
protected $table = 'links';
public $incrementing = false;
public $timestamps = true;
protected $primaryKey = "id";
protected $fillable = ['title', 'url'];
public function events()
{
return $this->belongsToMany('App\Event')->withTimestamps();
}
}
Event Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
protected $table = 'events';
public $incrementing = false;
public $timestamps = true;
protected $primaryKey = "id";
protected $fillable = ['description', 'date', 'image', 'category_id'];
public function category()
{
return $this->belongsTo('App\Event', 'category_id');
}
public function links()
{
return $this->belongsToMany('App\Link', 'event_link')->withTimestamps();
}
public function history()
{
return $this->belongsToMany('App\User', 'user_history');
}
public function favourites()
{
return $this->belongsToMany('App\User', 'user_favourites');
}
}
The problem is public $incrementing = false;: Remove the line from both your models.
Your id columns are defined as AUTO_INCREMENT, so $incrementing has to be true.

Eloquent create says column has no default value using Laravel 5

I have an small API that i want to save into client mysql database.
For this purpose i'm using guzzle.
my controller:
public function index()
{
$http = new \GuzzleHttp\Client;
$res = $http->request('GET', 'http://localhost:8080/api/address');
$addresses = json_decode($res->getBody(),true);
// dd($addresses);
Address::create($addresses);
}
my model:
class Address extends Model
{
protected $primaryKey = 'Adresse';
protected $fillable = ['Adresse', 'Mandant', 'Kategorie', 'Matchcode', 'Name1'];
public $timestamps = false;
}
my migration:
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->integer('Adresse')->primary();
$table->smallInteger('Mandant');
$table->smallInteger('Kategorie')->nullable();
$table->string('Matchcode', 50);
$table->string('Anrede', 50)->nullable();
$table->string('Name1', 50)->nullable();
});
}
my api content:
[
{"Adresse":"1111","Mandant":"0","Kategorie":"0","Matchcode":"fgh8881","Anrede":"Firma","Name1":"Sample name"},{"Adresse":"2399","Mandant":"0","Kategorie":"0","Matchcode":"fgh8882","Anrede":"Firma","Name1":"Sample name 1"}
]
the problem is i get an error
SQLSTATE[HY000]: General error: 1364 Field 'Adresse' doesn't have a
default value (SQL: insert into addresses () values ())
when i limit the api content to one array i can save it without a problem. But if i have more arrays in my api i get this error.
$fillable property on the model is set.
If your primary key is not auto-incrementing the framework needs to know about it.
class Address extends Model
{
protected $primaryKey = 'Adresse';
protected $fillable = ['Adresse', 'Mandant', 'Kategorie', 'Matchcode', 'Name1'];
public $incrementing = false;
public $timestamps = false;
}
Then to add all of the models:
public function index()
{
$http = new \GuzzleHttp\Client;
$res = $http->request('GET', 'http://localhost:8080/api/address');
$addresses = json_decode($res->getBody(),true);
foreach ($addresses as $address) {
Address::create($address);
}
}
Your API content is essentially 2 records. For mass inserting using eloquent you need to use insert not create
So either
1) have your api return 1 result
2) or change Address::create($addresses); to Address::insert($addresses);
Set Adresse be auto-increment as well with primary key and your issue will be solved or If you do not want to set it to auto-increment then assign it to a default value.
check the table structure of addresses whether it have default value NULL need to change default

Inserting to multiple table with foreign key in Laravel Eloquent

These is my first time using the laravel framework and so far it is well structure than others i have used. But these have left me struck in an error i have been debugging a while.
I have a Post model that have sub model Post Images and Post Location. I am trying to insert data to the Post Images and then get the id of the save data into the base Model Post so i can make the relationship these are my code
Post Model
class Post extends Model {
protected $table = 'posts';
public $primaryKey = 'id';
public function user(){
return $this->belongsTo('App\User');
}
public function post_image(){
return $this->belongsTo('App\PostImage');
}
public function location(){
return $this->belongsTo('App\PostLocation');
}
}
Migrated From create post
public function up(){
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('user_id')->unsigned();
$table->integer('location_id')->unsigned();
$table->integer('post_image_id')->unsigned();
$table->timestamps();
});
Base model Relationship are
class PostImage extends Model{
protected $table = 'post_images';
public $primaryKey = 'id';
public function post(){
return $this->belongsTo('App\Post');
}
}
class PostLocation extends Model{
protected $table = 'location';
public $primaryKey = 'id';
public function post(){
return $this->belongsTo('App\Location');
}
}
In the Post Controller store method. I am saving the post image first and then try to reference the inserted table id as the foreign key and error occur after a while i try to different combination it doesnt work. The images are sucecfully save but the reference dosent work
Post controller store code
public function store(Request $request){
$this->validate($request, [
// Validation work here
]);
// Function to save images work perfectly and return the an array containg image
$images = $this->uploadAssetImages($request);
$post= new Post();
$image = new PostImage();
$image->image1 = $images[0];
$image->image2 = $images[1];
$image->image3 = $images[2];
$image->save();//$image->id()
//I have try these: $image_id = Response::json(array('success' => true, 'last_insert_id' => $image->id), 200);
$asset->description = $request->input('description');
$asset->user_id = auth()->user()->id;
$asset->post_image()->save($image);// After debuging error is found here
$asset->save();
Hope these can be resolve?

Categories