Below is a piece of code from my Register Controller. As you can see, every field has a value, but its not inserting into database. I have configured default values to these fields in database, if values are not present. It gives row don't have default value. I am unable to figure out the problem. I also have all fields fillable in Models.
protected function create(array $data)
{
$user = Account::create([
'wallet' => $data['wallet'],
'email' => $data['email'],
'balance' => 0,
'uqid' => rand(10000000,99999999) ,
'ref' => 0,
]);
$gnl = General::first();
$track = Track::create([
'account_id' => $user->id,
'speed' => $gnl->dhs_free,
'balance' => 0,
'uqid' => rand(10000000,99999999) ,
'ref' => 0,
]);
Account Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Account extends Model
{
protected $fillable = ['wallet','uqid','ref','bstatus','refcom','email','verified'];
public function deposit()
{
return $this->hasMany('App\Deposit','id','account_id');
}
public function withdraw()
{
return $this->hasMany('App\Withdraw','id','account_id');
}
public function track()
{
return $this->hasMany('App\Track','id','account_id');
}
Track Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Track extends Model
{
protected $fillable = array( 'account_id','speed','withdraw','status');
public function account()
{
return $this->belongsTo('App\Account');
}
}
When using the create function, it seems you are not filling all the fields in the table.
Either, ensure you're assigning values to all fields in the create() function, or ensure there are default values in the database. In the builder, use ->default(0) or something.
There are few things which can be identified in your code :
Firstly the number and name of the columns in the Model and create method are different :
Account Model contains :
protected $fillable = ['wallet','uqid','ref','bstatus','refcom','email','verified'];
But your create contains :
'wallet' => $data['wallet'],
'email' => $data['email'],
'balance' => 0,
'uqid' => rand(10000000,99999999) ,
'ref' => 0,
Create does not contain bstatus, refcom and so on... columns but those are present in your Model and in the database table.
Similarly, Track Model contains :
protected $fillable = ['account_id','speed','withdraw','status'];
But its create contains :
'account_id' => $user->id,
'speed' => $gnl->dhs_free,
'balance' => 0,
'uqid' => rand(10000000,99999999) ,
'ref' => 0,
Now, if your non-specified columns in create() function do not have any default value specified in database, you will get :
Error : row don't have default value
Solution either add values to those columns in create() or mark those columns are nullable using a migration.
Related
I'm new to laravel,
I wanted to insert student details in mysql database from xlsx file.
I used Laravel excel v3 to import excel file. It is working good. But along with inserting student details in 1 table, The same student id record should be made in all associative tables.
example -->
if 1 student inserted in table 'student_details', then 1 record must be made in tables 'oral' and 'endsem' having foreign key as 'student_id'.
I have made event to make this records in oral and endsem tables.
Now problem is how to apply that event and how to get that student_id after student is created to fire event.
(Student Id will is auto_increment value)
StudentImport -->
<?php
namespace App\Imports;
use App\Events\StudentCreated;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Validators\Failure;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\SkipsFailures;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use App\Models\StudentDetails;
class StudentsImport implements ToModel, SkipsOnFailure, WithValidation, WithHeadingRow
{
use Importable, SkipsFailures;
/**
* #param Collection $collection
*/
public function model(array $row)
{
return new StudentDetails([
'roll_no' => $row['roll_no'],
'student_id' => $row['student_id'],
'div' => $row['div'],
'name' => $row['name'],
'gender' => $row['gender'],
'user_key' => session()->get('user_id'),
'group_key' => $group_key
]);
}
public function onFailure(Failure ...$failures)
{
// Handle the failures how you'd like.
}
public function rules(): array
{
return [
'student_id' =>[
'required',
'string',
'unique:student_details'
],
'roll_no' =>[
'required',
'integer'
],
'name' => [
'required',
'string',
]
];
}
}
My main goal is to insert student record in all associative tables having foreign key 'student_id' when student is inserted in 'student_details' table.
If there is any other way, please help.
Instead of using
Maatwebsite\Excel\Concerns\ToModel you could use Maatwebsite\Excel\Concerns\OnEachRow. You'd get more control over what happens on every row.
use App\StudentDetails;
use Maatwebsite\Excel\Row;
use Maatwebsite\Excel\Concerns\OnEachRow;
class StudentsImport implements OnEachRow, ...
{
public function onRow(Row $row)
{
$rowIndex = $row->getIndex();
$row = $row->toArray();
// create model
$studentDetails = StudentDetails::create([
'roll_no' => $row['roll_no'],
'student_id' => $row['student_id'],
'div' => $row['div'],
'name' => $row['name'],
'gender' => $row['gender'],
'user_key' => session()->get('user_id'),
'group_key' => $group_key /* this variable doesn't seem to be defined anywhere */
]);
// create related models
$studentDetails->oral()->create([...]);
$studentDetails->endsem()->create([...]);
}
}
As for making this all happen within a transaction:
DB::transaction(fn () => (new StudentsImport)->import(...));
in my web application i have this models:
InstagramAccount.php
UserPageFeed.php
each InstagramAccount has one record into UserPageFeed and each UserPageFeed belongs to one record into InstagramAccount, then that's one to one relationship,
PROBLEM:
my below code couldn't update existing row on table and create again
$userSelectedPage = InstagramAccount::whereUsername('my_page')->first();
$userPageFeeds = new UserPageFeed();
$userSelectedPage->account()->updateOrCreate([
'instagram_account_id' => $userPageFeeds->id, //exsiting row
'page_name' => 'test',
'feeds' => 'test',
'cache_time' => Carbon::now()->addHour(6),
]);
or this code:
$userSelectedPage = InstagramAccount::whereUsername('content.world')->first();
$salam = $userSelectedPage->account()->updateOrCreate([
'instagram_account_id' => $userSelectedPage->id,
'page_name' => 'aaaaaaa',
'feeds' => 'ddd',
'cache_time' => Carbon::now()->addHour(6),
]);
user_page_feeds table structure:
id ->Primary
instagram_account_id ->Index
feeds
page_name
cache_time
created_at
updated_at
with this index:
"Keyname":user_page_feeds_instagram_account_id_foreign "Column":instagram_account_id
instagram_accounts table structure:
id ->Primary
user_id ->Index
uid
fid
proxy
avatar
username
password
checkpoint
account_data
people_data
status
created_at
updated_at
InstagramAccount model:
class InstagramAccount extends Model
{
protected $guarded = ['id'];
protected $casts = [
'account_data' => 'array',
'people_data' => 'array'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function account()
{
return $this->hasOne(UserPageFeed::class);
}
}
UserPageFeed model:
class UserPageFeed extends Model
{
public $incrementing = false;
protected $guarded = ['id'];
protected $casts = [
'feeds' => 'array'
];
public function account()
{
return $this->belongsTo(InstagramAccount::class,'instagram_account_id');
}
}
You have to use updateOrCreate() with two separate parameters:
$userSelectedPage->account()->updateOrCreate(
['instagram_account_id' => $userPageFeeds->id],
[
'page_name' => 'test',
'feeds' => 'test',
'cache_time' => Carbon::now()->addHour(6),
]
);
The first parameter contains the attributes that Laravel uses to find the existing
account.
The second parameter contains the attributes that Laravel uses to create or update the account.
I am trying to use a $defaultIncludes() and am getting an exception --
ErrorException in ViewoptionTransformer.php line 8:
Argument 1 passed to App\Transformers\ViewoptionTransformer::transform() must be an instance of App\Viewoption, boolean given
Following the tutorial (http://laravelista.com/build-an-api-with-lumen-and-fractal/) except I am using Laravel 5.1 not Lumen:
in User model, I have the hasOne relationship with Viewoption called viewoptions
In the UsersController, I eager load viewoptions
public function index(Manager $fractal, UserTransformer $userTransformer)
{
$records = User::with(['locations', 'viewoptions'])->get();
$collection = new Collection($records, $userTransformer);
$data = $fractal->createData($collection)->toArray();
return $this->respondWithCORS($data);
}
In the UserTransformer, I have the $defaultInclude and the includes method
protected $defaultIncludes = ['viewoptions'];
`public function transform(User $user)
{
return [
'id' => $user->id,
'name' => $user->name,
'is_active' => (boolean)$user->is_active,
'is_admin' => (boolean)$user->is_admin,
'is_manager' => (boolean)$user->is_manager,
'role_id' => (integer) $user->role_id,
'email' => $user->email,
'phone' => $user->phone,
'full_sidebar' => (boolean)$user->full_sidebar
];
}
public function includeViewoptions(User $user)
{
$viewoptions = $user->viewoptions;
return $this->collection($viewoptions, new ViewoptionTransformer);
}`
Have a ViewoptionTransformer
`
use App\Viewoption;
use League\Fractal\Resource\Collection;
use League\Fractal\TransformerAbstract;
class ViewoptionTransformer extends TransformerAbstract {
public function transform(Viewoption $item)
{
//return $item;
return [
'id' => $item->id,
'user_id' => $item->user_id,
'voAgency' => (boolean)$item->voAgency,
'voBalanceDue' => (boolean)$item->voBalanceDue,
'voCloseDate' => (boolean)$item->voCloseDate,
'voCommitTotal' => (boolean)$item->voCommitTotal,
'voDistributor' => (boolean)$item->voDistributor,
'voDueDate' => (boolean)$item->voDueDate,
'voFeePercentage' => (boolean)$item->voFeePercentage,
'voRegion' => (boolean)$item->voRegion,
'voSeason' => (boolean)$item->voSeason,
];
}
}`
Worked with these and slight variations of these throughout the day yesterday and I can't rid myself of that exception.
Not all of your users.id corresponds to some viewoptions.user_id.
Just check it:
$records = User::with(['locations', 'viewoptions'])->get();
dd($records);
some viewoptions will be null or false or just undefined
Instead of using collection use item like so
public function includeViewoptions(User $user){
$viewoptions = $user->viewoptions;
return $this->item($viewoptions, new ViewoptionTransformer);
}`
I had a similar issue today, all my other uses of transformers had been with hasMany relationships. I was always instantiating the transformer with a collection of objects.
However, when using a transformer with a belongsTo relationship and instantiating the transformer with only one object (similar to how you are passing only one object from a hasOne relationship) I would get the same boolean given error.
In the end I solved the issue by using 'item' instead of 'collection' when instantiating the transformer.
Within your includeViewoptions function
Instead of using
return $this->collection($viewoptions, new ViewoptionTransformer);
try
return $this->item($viewoptions, new ViewoptionTransformer);
Here is my model relationship...
class User extends Eloquent {
public function loginLog(){
return $this->hasMany('LoginLog');
}
}
class LoginLog extends Eloquent {
public function user(){
return $this->belongsTo('User');
}
}
When I insert data into the login_logs table in my database all the data is input correctly but it does not insert the id of the user into user_id (laravel expects this).
Here is how I am inserting into login_logs.
$user->loginLog()->insert(array(
'user_id' => $user->id, //I could put it here, but then what is the point in a relationship?
'email' => $user->email,
'ip_address' => Request::getClientIp(),
'country_code' => $country_code,
'status' => $status,
'created_at' => Helper::dateTimeNow()
));
You have to attach the user.
Its here in the docs
http://laravel.com/docs/eloquent#inserting-related-models
Update:
On rereading your question I think you want to find the user by their id first as you are doing $user->loginLog()->insert not $loginLog->insert
Try chaining it so:
$user::find($theIDYouWant)->loginLog()->insert
I don't want to use rows 'update_at' and 'create_at', but Laravel's seed file is trying to update it. How can I disable it?
Here is the code that I'm using:
use Illuminate\Database\Migrations\Migration;
class SeedUsersTable extends Seeder {
// $timestamps = false; <=== will return error
// public static $timestamps = false; <=== will return error
public function run()
{
DB::table('users')->delete();
User::create(array(
'id' => 1,
'name' => 'Админ',
'password' => Hash::make('admin'),
'login' => 'admin'
));
}
}
According to the Laravel docs,
... by default, Eloquent will maintain the created_at and updated_at columns on your database table automatically. Simply add these timestamp columns to your table and Eloquent will take care of the rest.
If you do not wish for Eloquent to maintain these columns, In your User model add the following:
class User extends Eloquent {
public $timestamps = false;
}
use Illuminate\Database\Migrations\Migration;
class SeedUsersTable extends Seeder {
public function run()
{
DB::table('users')->delete();
$user = new User(array(
'id' => 1,
'name' => 'Админ',
'password' => Hash::make('admin'),
'login' => 'admin'
));
$user->timestamps = false;
$user->save();
}
}