Laravel Eloquent after save id becomes 0 - php

It's a table migrated from https://github.com/lucadegasperi/oauth2-server-laravel
In the table oauth_clients, the field data type of id is varchar(40), not int.
$name = Input::get('name');
$id = str_random(40);
$secret = str_random(40);
$client = new oauthClient;
$client->name = $name;
$client->id = $id;
$client->secret = $secret;
$client->save();
After save(); the $client->id become '0', not the string I assigned.
That makes the following relation table save fail.
$endpoint = new OauthClientEndpoint(array('redirect_uri' => Input::get('redirect_uri));
$client->OauthClientEndpoint()->save($endpoint);
I checked the $client->id: after save, it becomes 0 and I get an error including this one:
(SQL: insert into `oauth_client_endpoints` (`redirect_uri`, `client_id`, `updated_at`, `created_at`) values (http://www.xxxxx.com, 0, 2014-09-01 11:10:16, 2014-09-01 11:10:16))
I manually saved an endpoint to prevent this error for now. But how do I resolve this issue?
Here's my model:
class OauthClient extends Eloquent {
protected $table = 'oauth_clients';
public function OauthClientEndpoint(){
return $this->hasOne('OauthClientEndpoint', 'client_id', 'id');
}
}
class OauthClientEndpoint extends Eloquent {
protected $table = 'oauth_client_endpoints';
protected $fillable = array('redirect_uri');
public function OauthClient(){
return $this->belongsTo('OauthClient', 'client_id', 'id');
}
}
class CreateOauthClientsTable extends Migration {
public function up() {
Schema::create('oauth_clients', function (Blueprint $table) {
$table->string('id', 40);
$table->string('secret', 40);
$table->string('name');
$table->timestamps();
$table->unique('id');
$table->unique(array('id', 'secret'));
});
}
public function down() {
Schema::drop('oauth_clients');
}
}
class CreateOauthClientEndpointsTable extends Migration {
public function up() {
Schema::create('oauth_client_endpoints', function (Blueprint $table) {
$table->increments('id');
$table->string('client_id', 40);
$table->string('redirect_uri');
$table->timestamps();
$table->foreign('client_id')
->references('id')->on('oauth_clients')
->onDelete('cascade')
->onUpdate('cascade');
});
}
public function down() {
Schema::table('oauth_client_endpoints', function ($table) {
$table->dropForeign('oauth_client_endpoints_client_id_foreign');
});
Schema::drop('oauth_client_endpoints');
}
}

When you are setting your own ID and not using auto_increment be sure to add public $incrementing = false; to that model. In your case you want:
class OauthClient extends Eloquent {
public $incrementing = false;
protected $table = 'oauth_clients';
public function OauthClientEndpoint(){
return $this->hasOne('OauthClientEndpoint', 'client_id', 'id');
}
}
This is a tiny red block in the huge Laravel documentation:
Note: Typically, your Eloquent models will have auto-incrementing keys. However, if you wish to specify your own keys, set the incrementing property on your model to false.

Related

How to restrict delete / destroy method when model has association with another model / id?

I have model called GroupService and it has association with Service. I want to prevent or restrict when deleting GroupService, if GroupService has association with Service. And if GroupService has no association then users can delete it. I've been following these guides but it's not working for me :
[1] Laravel - How to prevent delete when there is dependent field
[2] https://laracasts.com/discuss/channels/laravel/how-to-prevent-the-delete-of-table-row-that-has-its-id-in-another-table
Here's my code :
Model GroupService:
class GroupService extends Model
{
use HasFactory;
protected $table = 't_grup_layanan';
protected $guarded = ['id'];
// protected $fillable = [
// 'bisnis_id',
// 'deskripsi'
// ];
protected $with = ['business'];
public function service(){
return $this->hasMany(Service::class);
}
public function business(){
return $this->belongsTo(Business::class, 'bisnis_id');
}
// protected static function boot(){
// parent::boot();
// static::deleting(function($groupservice) {
// $relationMethods = ['service'];
// foreach ($relationMethods as $relationMethod) {
// if ($groupservice->$relationMethod()->count() > 0) {
// return false;
// }
// }
// });
// }
}
Model Service:
class Service extends Model
{
use HasFactory;
protected $table = 't_layanan';
protected $guarded = ['id'];
// protected $fillable = [
// 'gruplayanan_id',
// 'nama',
// 'deskripsi'
// ];
protected $with = ['groupservice'];
public function groupservice(){
return $this->belongsTo(GroupService::class, 'gruplayanan_id');
}
}
Controller GroupService:
public function destroy(GroupService $groupservice, $id)
{
$groupService = GroupService::find(Crypt::decrypt($id));
if ($groupService->service()->exists())
{
abort('Resource cannot be deleted due to existence of related resources.');
}
$groupService->delete();
return redirect('/dashboard/gruplayanan/')->with('danger', 'Data dihapus !');
}
Migration GroupService:
public function up()
{
Schema::create('t_grup_layanan', function (Blueprint $table) {
$table->id();
$table->foreignId('bisnis_id')->nullable()->index('fk_bisnis_to_group');
$table->text('deskripsi');
$table->timestamps();
});
}
Migration Service:
public function up()
{
Schema::create('t_layanan', function (Blueprint $table) {
$table->id();
$table->foreignId('gruplayanan_id')->index('fk_grup_to_layanan');
$table->text('nama');
$table->text('deskripsi');
$table->timestamps();
});
}
public function up()
{
Schema::table('t_layanan', function (Blueprint $table) {
$table->foreign('gruplayanan_id', 'fk_grup_to_layanan')->references('id')->on('t_grup_layanan')->onUpdate('CASCADE')->onDelete('CASCADE');
});
}
I think problem is here on your relationship function:
public function service(){
return $this->hasMany(Service::class);
}
By Laravel convention, Eloquent will take the table name parent model and suffix it with _id.
So it look for t_grup_layanan_id field in the t_layanan table which currently does not exist.
So if you want to override the default convention, you have to specify it on the 2nd parameter like this.
public function service(){
return $this->hasMany(Service::class, 'gruplayanan_id');
}

Laravel Error: Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute()

I am getting the following error while trying to insert into the table users_basics
Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed in
C:\xampp\htdocs\msadi\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php
on line 592 and exactly 2 expected
Here is my controller code:
public function create()
{
$userId = '10';
$userBasics = new UserBasics;
$userBasics->user_id = $userId;
$userBasics->save();
return redirect('users');
}
Here is my model:
class UserBasics extends Model
{
protected $table = 'users_basics';
protected $primaryKey = null;
protected $fillable = ['user_id'];
const UPDATED_AT = null;
const CREATED_AT = null;
}
Here is my user_basics migration:
public function up()
{
Schema::create('users_basics', function (Blueprint $table) {
$table->integer('user_id');
$table->bigInteger('adhaar_no')->nullable();
$table->string('mobile_no')->nullable();
$table->string('college_roll_no')->nullable();
$table->date('dob')->nullable();
$table->index('user_id');
});
}
I have tried adding UPDATED_AT, CREATED_AT and PrimaryKey to the table but none worked. The user_id is being inserted into the users_basics table but the error continues to show.
You should modify your model:
class UserBasics extends Model
{
protected $table = 'users_basics';
protected $primaryKey = null;
public $incrementing = false;
public $timestamps = false;
protected $fillable = ['user_id'];
}
because you not have field for Timestamp.
please add like this.
public function up()
{
Schema::create('sadi_users_basics', function (Blueprint $table) {
$table->integer('user_id');
$table->bigInteger('adhaar_no')->nullable();
$table->string('mobile_no')->nullable();
$table->string('college_roll_no')->nullable();
$table->date('dob')->nullable();
$table->timestamp(); <---- just insert this.
$table->index('user_id');
});
}
also, if you want to use softdelete then add $table->softDeletes();
it will make Deleted_at field in the table.
enjoy coding~!

ERROR SQLSTATE[HY000]: General error: 1364 Field 'name' doesn't have a default value (SQL: insert into `favorites` () values ())

I am trying to copy a station from the station repository and add it to my favorite repository. I am in a laravel rest API. Thanks for the help!
Here is my controller:
class FavoriteController extends Controller
{
private $favoriteRepository;
private $stationRepository;
public function __construct(FavoriteRepository $favoriteRepository, StationRepository $stationRepository)
{
$this->favoriteRepository = $favoriteRepository;
$this->stationRepository = $stationRepository;
}
public function store(int $station_id)
{
$favorite = array();
$favorite[] = $this->stationRepository->findByField("id", $station_id);
$this->favoriteRepository->create($favorite);
return response()->json($favorite, 201);
}
}
Here is the database for the favorites:
public function up()
{
Schema::create('favorites', function (Blueprint $table) {
$table->string('name');
$table->string('city');
$table->foreign('city')->references('name')->on('cities');
$table->integer('station_id')->unsigned();
$table->foreign('station_id')->references('id')->on('stations')->onDelete('cascade');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
#$table->boolean('is_private');
});
}
Here is my Favorite model
class Favorite extends Model
{
protected $fillable = ['station_id', 'user_id', 'updated_at', 'name', 'city'];
public $timestamps = false;
}
And I have both these methods in my repos:
function model()
{
return "App\\Station";
}
Try this
public function store($station_id)
{
$favorite = $this->stationRepository->where("id", $station_id)->first()->toArray();
$this->favoriteRepository->create($favorite);
return response()->json($favorite, 201);
}
}

Laravel 5.1 Foreign Key Trouble

I have some trouble getting the foreign key.
My Migrations looks like this (shortened them):
<?php
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('email');
$table->string('title');
$table->string('filename');
$table->integer('number_of_chapters');
$table->text('input_mpg');
$table->timestamps();
});
}
public function down()
{
Schema::drop('products');
}
}
<?php
class CreateChaptersTable extends Migration
{
public function up()
{
Schema::create('chapters', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->time('input-chapter-start1');
$table->time('input-chapter-end1');
$table->timestamps();
});
Schema::table('chapters', function($table) {
$table->foreign('product_id')->references('id')->on('products');
});
}
public function down()
{
Schema::drop('chapters');
}
}
And my 2 Model like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chapters extends Model
{
protected $table = 'chapters';
protected $fillable = ['input-chapter-start1', 'input-chapter-end1'];
public function product()
{
return $this->belongsTo('App\Product');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = 'products';
protected $fillable = ['email', 'title', 'filename', 'inputMpg', 'number_of_chapters'];
public static $rules = [
'email' => 'required|email|max:50',
'title' => 'required|max:50',
'filename' => 'required|max:50',
'input_mpg' => 'required'
];
public function Chapters()
{
return $this->hasMany('App\Chapters');
}
}
And just save it like this in my Controller
$product->save();
$Chapters->save();
And get following error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(generator.chapters, CONSTRAINT chapters_product_id_foreign
FOREIGN KEY (product_id) REFERENCES products (id)) (SQL: insert
into chapters (input-chapter-start1, input-chapter-end1,
updated_at, created_at) values (12:12:12, 12:12:12, 2016-04-25
11:41:31, 2016-04-25 11:41:31))
EDIT
Controller looks like this:
namespace App\Http\Controllers;
class ProductController extends Controller
{
protected $request;
public function request(Request $request)
{
$this->request = $request;
}
public function createProduct(Request $request)
{
$product = new Product;
$Chapters = new Chapters($request->all());
$data = $request->all();
$projectEmail = $request->input('email');
$projectTitle = $request->input('title');
$projectFile = $request->input('filename');
$projectChapters = $request->input('number_of_chapters');
$validator = Validator::make($request->all(), Product::$rules);
if($validator->fails())
{
return Redirect::back()->withInput()->withErrors($validator);
}
$product->fill($data);
if($product->save())
{
$Chapters->product()->associate($product);
$Chapters->save();
return redirect()->route('root')->with('message', 'success')->withInput();
}
else
{
return redirect()->route('newProduct')->with('message', 'Error')->withInput();
}
}
}
Edit I tried Samsquanch suggestion:
And added this in my controller:
$product->save();
$Chapters->product()->associate($product);
$Chapters->save();
but still get this error message:
BadMethodCallException in Builder.php line 2093: Call to undefined
method Illuminate\Database\Query\Builder::products()
The problem is that you're not telling Laravel or MySQL what the foreign key should be.
You have two options here (both from the documentation: https://laravel.com/docs/5.1/eloquent-relationships#inserting-related-models)
The first option would be to save chapters through product:
$chapters = $product->chapters()->saveMany($Chapters); // or just->save() if it's only one
The second (and how I generally do it) would be to use associate() which relies on the belongsTo relationship in your Chapters model:
$product->save();
$Chapters->product()->associate($product);
$Chapters->save();
There's also a third, but not recommended, option of just setting the foreign key yourself manually.
Edit:
$product->chapters()->associate($Chapters);
$product->save();

Laravel eloquent unconventional column not working

Hi laravel is not inserting correct value in pivot table for many to many case.
Here my first model is
class ShippingAddress extends Eloquent {
protected $guarded = array('id');
protected $table = 'shippingAddress';
public function mwsOrder()
{
return $this->belongsToMany('MwsOrder',
'mwsOrders_shippingAddress',
'Address_id',
'AmazonOrderId'
);
}
}
Second Model is
class MwsOrder extends Eloquent {
protected $table = 'mwsOrders';
protected $primaryKey = 'AmazonOrderId';
public function shippAddress()
{
return $this->belongsToMany('ShippingAddress',
'mwsOrders_shippingAddress',
'AmazonOrderId',
'Address_id'
);
}
}
EER Diagram
Now when i run this
$mwsOrder = new MwsOrder;
$mwsOrder->AmazonOrderId = 'Eve 6';
$mwsOrder->save();
$address = new ShippingAddress;
$address->name = 'Naruto Uzumaki';
$address->save();
$address->mwsOrder()->attach($mwsOrder);
//$mwsOrder->shippAddress()->save($address);
laravel throws error and this is what laravel trying to run the query
(SQL: insert into mwsOrders_shippingAddress (Address_id,
AmazonOrderId) values (1, 3))
What i need is to generate this query
insert into mwsOrders_shippingAddress (Address_id,
AmazonOrderId) values (1, 'Eve 6')
Update:
Schema are:
Schema::create("shippingAddress", function(Blueprint $table)
{
$table->increments("id");
$table->string("Name");
$table->timestamps();
});
Schema::create("mwsOrders", function(Blueprint $table)
{
$table->increments("id");
$table->string("AmazonOrderId")->unique();
$table->timestamps();
});
Schema::create("mwsOrders_shippingAddress", function(Blueprint $table)
{
$table->increments("id");
$table->string("AmazonOrderId");
$table->foreign("AmazonOrderId")->references("AmazonOrderId")->on('mwsOrders');
$table->integer("shipping_address_id")->unsigned();
$table->foreign("shipping_address_id")->references('id')->on('shippingAddress');
$table->timestamps();
});
At first change the shippAddress to this:
// Specify the primary key because it's not conventional id
protected $primaryKey = 'AmazonOrderId';
public function shippAddress()
{
return $this->belongsToMany('ShippingAddress',
'mwsOrders_shippingAddress',
'AmazonOrderId',
'Address_id'
);
}
Then you may try this:
$mwsOrder = new MwsOrder;
$mwsOrder->AmazonOrderId = 'Eve 6';
$mwsOrder->save();
$address = new ShippingAddress(['name' => 'Naruto Uzumaki']);
$mwsOrder->shippAddress()->save($address); // Save and Attach

Categories