Field doesnt have a default value while importing excel laravel - laravel

i want to import excel file to my database from the web. I have no idea what make it doesnt get the value from the excel, because i already try dd it and it shows the collection from the excel like what i want to do with it.
but its show error
SQLSTATE[HY000]: General error: 1364 Field 'kode_matkul' doesn't have a default value (SQL: insert into kelas () values ())
route :
Route::post('/admin/import_kelas_excel', 'DashboardController#importKelasExcel');
controller:
public function importKelasExcel(Request $request)
{
Excel::import(new KelasImport, $request->file('file'));
return redirect('admin/list_kelas')->with('status', 'Excel Berhasil Diimport !');
}
KelasImport :
namespace App\Imports;
use App\Kelas;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class KelasImport implements ToCollection, WithHeadingRow
{
public function collection(Collection $rows)
{
foreach ($rows as $row) {
Kelas::updateOrCreate([
'id' => $row['nomor'],
], [
'id' => $row['nomor'],
'kode_matkul' => $row['kode'],
'nama_matkul' => $row['matakuliah'],
'grup' => $row['grup'],
'sifat' => $row['sifat'],
'sks' => $row['sks'],
'jumlah_mhs' => $row['jumlah_mahasiswa'],
'tahun_ajaran' => $row['tahun_ajaran'],
'semester' => $row['semester'],
'jumlah_dosen' => $row['jumlah_dosen'],
]);
}
}
model :
protected $table="kelas";
protected $fillable = ["kode_matkul, nama_matkul, grup, sifat, sks, jumlah_mhs, prodi, tahun_ajaran, semester"];
public $timestamps = false;
excel :

Related

Laravel - Update a table using Maatwebsite Excel Import based on condition

Using Laravel-5.8 and Maatwebsite-3.1, I have a table called employees (Employee).
class FirstEmployeeSheetImport implements ToModel, WithBatchInserts, WithHeadingRow, SkipsOnError, WithValidation, SkipsOnFailure
{
use Importable, SkipsErrors, SkipsFailures;
public function model(array $row)
{
$this->department = $row['department'];
$employee_data = [
'employee_code' => $row['employee_code'],
'company_id' => Auth::user()->company_id,
'email' => $row['official_email'],
'department_id' => $this->getDepartment(),
];
$employee = Employee::create($employee_data);
}
public function getDepartment(){
if(!empty($this->department) || !$this->department){
return HrDepartment::where('dept_name',$this->department)->where('company_id',Auth::user()->company_id)->pluck('id')->first();
} else {
return 0;
}
}
}
I want to use the excel upload to update these two (2) fields: email and department_id for each of the employees where:
company_id = Auth::user()->company_id AND employee_code = $row['employee_code'].
Also, it should only perform the update for those that meet the condition. I should only perform update and don't crete.
How do I achieve this?
Thanks
You can use ToCollection to get your data into $rows then update your data accordingly.
class FirstEmployeeSheetImport implements ToCollection
{
public function collection(Collection $rows)
{
foreach ($rows as $row)
{
Employee::where('company_id', auth()->user()->company_id)
->where('employee_code', $row['employee_code'])
->update([
'email' => $row['email'],
...
]);
}
}
}

Laravel / OctoberCMS frontend filter

I am using OctoberCMS and I have created a custom component. I am trying to create a frontend filter to filter Packages by the Tour they are assigned to.
This is what I have so far. The issue is that the code is looking for a tour field within the packages table rather than using the tour relationship. Does anyone have any ideas?
<?php namespace Jakefeeley\Sghsportingevents\Components;
use Cms\Classes\ComponentBase;
use JakeFeeley\SghSportingEvents\Models\Package;
use Illuminate\Support\Facades\Input;
class FilterPackages extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Filter Packages',
'description' => 'Displays filters for packages'
];
}
public function onRun() {
$this->packages = $this->filterPackages();
}
protected function filterPackages() {
$tour = Input::get('tour');
$query = Package::all();
if($tour){
$query = Package::where('tour', '=', $tour)->get();
}
return $query;
}
public $packages;
}
I really appreciate any help you can provide.
Try to query the relationship when the filter input is provided.
This is one way to do it;
public $packages;
protected $tourCode;
public function init()
{
$this->tourCode = trim(post('tour', '')); // or input()
$this->packages = $this->loadPackages();
}
private function loadPackages()
{
$query = PackagesModel::query();
// Run your query only when the input 'tour' is present.
// This assumes the 'tours' db table has a column named 'code'
$query->when(!empty($this->tourCode), function ($q){
return $q->whereHas('tour', function ($qq) {
$qq->whereCode($this->tourCode);
});
});
return $query->get();
}
If you need to support pagination, sorting and any additional filters you can just add their properties like above. e.g;
protected $sortOrder;
public function defineProperties(): array
{
return [
'sortOrder' => [
'title' => 'Sort by',
'type' => 'dropdown',
'default' => 'id asc',
'options' => [...], // allowed sorting options
],
];
}
public function init()
{
$filters = (array) post();
$this->tourCode = isset($filters['tour']) ? trim($filters['tour']) : '';
$this->sortOrder = isset($filters['sortOrder']) ? $filters['sortOrder'] : $this->property('sortOrder');
$this->packages = $this->loadPackages();
}
If you have a more complex situation like ajax filter forms or dynamic partials then you can organize it in a way to load the records on demand vs on every request.e.g;
public function onRun()
{
$this->packages = $this->loadPackages();
}
public function onFilter()
{
if (request()->ajax()) {
try {
return [
"#target-container" => $this->renderPartial("#packages",
[
'packages' => $this->loadPackages()
]
),
];
} catch (Exception $ex) {
throw $ex;
}
}
return false;
}
// call component-name::onFilter from your partials..
You are looking for the whereHas method. You can find about here in the docs. I am not sure what your input is getting. This will also return a collection and not singular record. Use ->first() instead of ->get() if you are only expecting one result.
$package = Package::whereHas('tour', function ($query) {
$query->where('id', $tour);
})->get();

Laravel 7: How to use in data seeder array

How to make distinct inserts using a custom array using database seeder?
Using the following code:
$categories = ['Hardware', 'Software', 'Planning', 'Tools'];
foreach ($categories as $category) {
App\Category::insert([
'name' => $category,
'slug' => Str::slug($category),
]);
}
It doesn't work without a factory for a category that is the problem matter if I use insert or create.
It gives this error
Unable to locate factory for [App\Category].
at vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:273
269| */
270| protected function getRawAttributes(array $attributes = [])
271| {
272| if (! isset($this->definitions[$this->class])) {
> 273| throw new InvalidArgumentException("Unable to locate factory for [{$this->class}].");
274| }
275|
276| $definition = call_user_func(
277| $this->definitions[$this->class],
Thanks
Create an array of data in the run method of you seeder file
public function run()
{
$categories = [
['name' => 'Music'],
['name' => 'Gaming'],
['name' => 'Entertainment'],
['name' => 'Non-Profit & Activism'],
['name' => 'Other'],
];
foreach ($categories as $category) {
Category::create($category);
}
}
You are pushing all data into the Model, so you need to set fillable or guarded in the Model.
class Category extends Model
{
protected $guarded = [];
}
try using insert witch take an array as parameter:
public function run()
{
$inputs[] = ['name'=> 'Hardware'];
$inputs[] = ['name'=> 'Software'];
$inputs[] = ['name'=> 'Planning'];
$inputs[] = ['name'=> 'Tools'];
App\Category::insert($inputs);
}
or you can do it in another way:
public function run()
{
$inputsNames = ['Hardware', 'Software', 'Planning', 'Tools'];
foreach($inputsNames as $categoryName)
{
$inputs[]=['name'=>$categoryName];
}
App\Category::insert($inputs);
}

SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘proposal_db.userlogs’ doesn’t exist

I’m doing some customization inside the CakeDC/users plug-in. I created a table with name “user_logs” which consist of foreign key relationship with the actual “users” table provided by CakeDC/users.
I baked the “user_logs” model using command:
bin\cake bake model UserLogs --plugin CakeDC/Users
After user gets login I’m just generating log transaction inside the “user_logs” table. I added the following line inside the “/vendor/cakedc/users/src/Controller/Traits/LoginTrait.php” file under _afterIdentifyUser function:
$this->activity_log(‘Login’, ‘Login’, $user[‘id’]);
And activity_log function is added inside the src/Controller/AppController.php file:
function activity_log($page, $action, $id=null){
$this->loadModel(‘CakeDC/Users.Userlogs’);
$dataUserLog = $this->Userlogs->newEntity();
$dataUserLog['user_id'] = $this->request->session()->read('Auth.User.id');
if(!empty($id)){
$dataUserLog['reference_id'] = $id;
} else {
$dataUserLog['reference_id'] = 0;
}
$dataUserLog['activity_timestamp'] = date('Y-m-d H:i:s');
$dataUserLog['page'] = $page;
$dataUserLog['action'] = $action;
$this->Userlogs->save($dataUserLog);
}
vendor/cakedc/users/src/Model/Entity/UserLog.php file code:
namespace CakeDC\Users\Model\Entity;
use Cake\ORM\Entity;
class UserLog extends Entity
{
protected $_accessible = [
‘user_id’ => true,
‘reference_id’ => true,
‘activity_timestamp’ => true,
‘page’ => true,
‘action’ => true,
‘user’ => true
];
}
vendor/cakedc/users/src/Model/Table/UserLogsTable.php file code:
namespace CakeDC\Users\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UserLogsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('user_logs');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'className' => 'CakeDC/Users.Users'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmptyString('id', null, 'create');
$validator
->dateTime('activity_timestamp')
->allowEmptyDateTime('activity_timestamp');
$validator
->scalar('page')
->maxLength('page', 255)
->allowEmptyString('page');
$validator
->scalar('action')
->maxLength('action', 255)
->allowEmptyString('action');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
return $rules;
}
}
The surprise part is! this works on localhost but when I’m uploading code on a server it’s not working. On localhost I’ve PHP v7.3.4 and on server I’ve PHP v5.6.40. Can any one suggest what’s wrong with this why it’s working on localhost and not on server? Everything is same I’ve done almost everything cleared model cache on server as well but no luck. Please help.
Not really sure why CAKEPHP is looking for table “proposal_db.userlogs” on server whereas I created “user_logs” table on both local and server. Please suggest?

Eloquent does not add foreign key from relation

I could not find an answer to my problem and I hope I can describe it properly. I do hope to be able to provide all necessary information.
Bottom line: Why does the relations parent ID not get injected on creating a new database entry through the parent model.
I have an Occasions model which holds a collection of pictures. Within the addPicture ($name, $filepath) method the exception is thrown. As pointed out rhough code-comments
Occasion.php
// namespace + use directives omitted
class Occasion extends Model
{
use Sluggable;
protected $fillable = [ 'name', 'root-folder', 'path' ];
public function sluggable ()
{
return [
'slug' => [
'source' => [ 'root-folder', 'name', ],
],
];
}
public function pictures ()
{
return $this->hasMany(picture::class);
}
public function addPicture ($name, $filepath)
{
$thumbname = $this->getThumbFilename($filepath);
dump($this,$this->pictures()); // dump to check my data
$pic = Picture::create(compact('name', 'thumbname'));
// this line is never reached
$pic->createThumb($filepath);
}
...
}
Picture.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Spatie\Glide\GlideImage;
class Picture extends Model
{
protected $fillable = [ 'name', 'thumbname' ];
public function createThumb ($filepath)
{
$this->ppath = storage_path('app') . "/" . $filepath;
$this->tpath = storage_path('app/public/thumbs') . "/" . $this->getfilename($filepath);
GlideImage::create($this->ppath)->modify([ 'w' => 100, 'h' => 100, 'fit' => 'max' ])->save($this->tpath);
$this->save();
}
public function occasion ()
{
return $this->belongsTo(Occasion::class);
}
/* public function slideshow ()
{
return $this->belongsToMany(Slideshow::class);
}*/
private function getfilename ($path)
{
$tmp = array_slice(explode('/', $path), -3);
return str_replace(" ", "-", implode("-", $tmp));
}
}
The result of dump($this->pictures()); shows the relation and the columns used:
HasMany {#206 ▼
#foreignKey: "pictures.occasion_id"
#localKey: "id"
#query: Builder {#205 ▶}
#parent: Occasion {#215 ▶}
#related: Picture {#210 ▶}
}
But I'm getting an error message telling me that my occasion_id (in pictures table) is missing a default value. Looking at the built query the occasion_id is indeed missing. What I can't figure out is why said ID does not get injected as I am creating the new picture instance through an occasion-object.
QueryException
SQLSTATE[HY000]: General error: 1364 Field 'occasion_id' doesn't have a default value (SQL: insert into `pictures` (`name`, `thumbname`, `updated_at`, `created_at`) values (IMG_0015.JPG, 2006-PVanlage-06-IMG_0015.JPG, 2017-09-12 19:34:07, 2017-09-12 19:34:07))
I hope that all necessary information is provided.
First you need to add "occasion_id" to fillable array in App\Picture model. Secondly, you need to create occasion object first, then pass the ID addPicture to create picture object, see below
public Picture extends Model{
public $fillable = ['name', 'filepath', 'occasion_id'];
public function occasion(){
$this->belongsTo(App\Occassion::class);
}
}
public function addPicture ($name, $filepath, $occasion_id)
{
$thumbname = $this->getThumbFilename($filepath);
dump($this,$this->pictures()); // dump to check my data
$pic = Picture::create(compact('name', 'thumbname', 'occasion_id'));
// this line is never reached
$pic->createThumb($filepath);
}
There's a smarter way to do this, but this should work.

Resources