如何从导入的 Excel 批量附加数组数据的关系? Laravel、php
How To Mass Attach Relationship Of Arrays Data From Imported Excel? Laravel, php
我终于可以将 excel 数据导入数据库(虽然与通常导入的代码不同),但它无法附加关系。
三个 table:用户(第一个 table)、role_user(关系 table)和角色(第二个 table)
错误:在布尔值上调用成员函数 roles()
Screenshot of the error
UserImport.php
use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
class UserImport implements ToModel
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
return new User([
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => $row[15],
]);
}
}
AdminController.php(部分)
public function import_student(Request $request)
{
$this->validate($request, [
'file' => 'required|mimes:csv,xls,xlsx'
]);
$import = Excel::toArray(new UserImport(), $request->file('file'));
foreach($import[0] as $row) {
// dd($row[1].' '.$row[2]);
$arr[] = [
// If uncomment this id from here, remove [0] from foreach
// 'id' => $row[0],
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => Hash::make($row[15]),
];
}
if(!empty($arr)){
User::insert($arr)->roles()->attach(Role::where('name', 'Student'));
}
if($import) {
//redirect
return redirect()->back()->with(['success' => 'Data Berhasil Diimport!']);
} else {
//redirect
return redirect()->back()->with(['error' => 'Data Gagal Diimport!']);
}
}
我检查了数据库,果然,从 excel 导入数据是成功的...只是这段代码 ->roles()->attach(Role::where('name', 'Student'));
似乎只有在不是多数组数据时才有效(仅在 create 中有效, 不插入)。
有没有办法为所有插入的数组数据批量附加关系?
Is there a way to mass attach relationship for all inserted arrays data?
遗憾的是,没有。您必须实施自定义逻辑以将角色附加到您插入的用户。例如,您可以在当前导入的用户上添加一个布尔列 is_importing
。
首先将 is_importing
列添加到您的用户 table,然后:
public function import_student(Request $request)
{
$this->validate($request, [
'file' => 'required|mimes:csv,xls,xlsx'
]);
$import = Excel::toArray(new UserImport(), $request->file('file'));
foreach($import[0] as $row) {
// dd($row[1].' '.$row[2]);
$arr[] = [
// If uncomment this id from here, remove [0] from foreach
// 'id' => $row[0],
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => Hash::make($row[15]),
'is_importing' => true // here we set importing to true, so our "not fully imported students" are marked
];
}
if(!empty($arr)){
User::query()->insert($arr); //good, just be careful of the size limit of $arr, you may need to chunk it
$role = Role::query()->where('name', 'Student')->first();
$role->users()->syncWithoutDetaching(
User::query()->where('is_importing', true)->pluck('id')
);
// we add all of users to the $role
// don't forget to define the users relationship in your Role model
User::query()->update(['is_importing' => false]);
// we conclude our import by setting is_importing to false
}
if($import) {
//redirect
return redirect()->back()->with(['success' => 'Data Berhasil Diimport!']);
} else {
//redirect
return redirect()->back()->with(['error' => 'Data Gagal Diimport!']);
}
}
为什么你做不到 User::insert($arr)->roles()->attach(Role::where('name', 'Student'));
?
User::insert()
是 User::query()->insert()
的快捷方式,允许您批量插入数据。它很有用,因为它速度很快,但与 User::query()->update()
一样,它不允许您执行除插入查询以外的任何操作。
换句话说,调用...
User::query()->insert([
'col1' => 'val1',
'col2' => 'val2',
]);
...就像调用:
DB::statement('INSERT INTO users (col1, col2) VALUES (val1, val2)');
它会 return 根据查询状态(是否插入内容)为您提供一个布尔值,但仅此而已。
因此:
User::insert($arr)->roles()->attach(Role::where('name', 'Student')); // Call to a member function roles() on boolean
// because insert() returns a boolean it's like writing
true->roles()->attach(Role::where('name', 'Student')); // Call to a member function roles() on boolean
您在当前问题之后会立即遇到的代码中的另一个问题是 ->roles()->attach(Role::where('name', 'Student'))
将不起作用,因为 attach()
需要模型实例、id 或 id 数组。这里你给了一个查询构建器(Role::where('name', 'Student')
),你需要附加->first()
.
我终于可以将 excel 数据导入数据库(虽然与通常导入的代码不同),但它无法附加关系。
三个 table:用户(第一个 table)、role_user(关系 table)和角色(第二个 table)
错误:在布尔值上调用成员函数 roles() Screenshot of the error
UserImport.php
use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
class UserImport implements ToModel
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
return new User([
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => $row[15],
]);
}
}
AdminController.php(部分)
public function import_student(Request $request)
{
$this->validate($request, [
'file' => 'required|mimes:csv,xls,xlsx'
]);
$import = Excel::toArray(new UserImport(), $request->file('file'));
foreach($import[0] as $row) {
// dd($row[1].' '.$row[2]);
$arr[] = [
// If uncomment this id from here, remove [0] from foreach
// 'id' => $row[0],
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => Hash::make($row[15]),
];
}
if(!empty($arr)){
User::insert($arr)->roles()->attach(Role::where('name', 'Student'));
}
if($import) {
//redirect
return redirect()->back()->with(['success' => 'Data Berhasil Diimport!']);
} else {
//redirect
return redirect()->back()->with(['error' => 'Data Gagal Diimport!']);
}
}
我检查了数据库,果然,从 excel 导入数据是成功的...只是这段代码 ->roles()->attach(Role::where('name', 'Student'));
似乎只有在不是多数组数据时才有效(仅在 create 中有效, 不插入)。
有没有办法为所有插入的数组数据批量附加关系?
Is there a way to mass attach relationship for all inserted arrays data?
遗憾的是,没有。您必须实施自定义逻辑以将角色附加到您插入的用户。例如,您可以在当前导入的用户上添加一个布尔列 is_importing
。
首先将 is_importing
列添加到您的用户 table,然后:
public function import_student(Request $request)
{
$this->validate($request, [
'file' => 'required|mimes:csv,xls,xlsx'
]);
$import = Excel::toArray(new UserImport(), $request->file('file'));
foreach($import[0] as $row) {
// dd($row[1].' '.$row[2]);
$arr[] = [
// If uncomment this id from here, remove [0] from foreach
// 'id' => $row[0],
'nisn' => $row[1],
'name' => $row[2],
'username' => $row[3],
'email' => $row[4],
'kelas' => $row[5],
'jabatan' => $row[6],
'tempat_lahir' => $row[7],
'tgl_lahir' => $row[8],
'bulan_lahir' => $row[9],
'tahun_lahir' => $row[10],
'jenis_kelamin' => $row[11],
'agama' => $row[12],
'tahun_masuk' => $row[13],
'no_telp' => $row[14],
'password' => Hash::make($row[15]),
'is_importing' => true // here we set importing to true, so our "not fully imported students" are marked
];
}
if(!empty($arr)){
User::query()->insert($arr); //good, just be careful of the size limit of $arr, you may need to chunk it
$role = Role::query()->where('name', 'Student')->first();
$role->users()->syncWithoutDetaching(
User::query()->where('is_importing', true)->pluck('id')
);
// we add all of users to the $role
// don't forget to define the users relationship in your Role model
User::query()->update(['is_importing' => false]);
// we conclude our import by setting is_importing to false
}
if($import) {
//redirect
return redirect()->back()->with(['success' => 'Data Berhasil Diimport!']);
} else {
//redirect
return redirect()->back()->with(['error' => 'Data Gagal Diimport!']);
}
}
为什么你做不到 User::insert($arr)->roles()->attach(Role::where('name', 'Student'));
?
User::insert()
是 User::query()->insert()
的快捷方式,允许您批量插入数据。它很有用,因为它速度很快,但与 User::query()->update()
一样,它不允许您执行除插入查询以外的任何操作。
换句话说,调用...
User::query()->insert([
'col1' => 'val1',
'col2' => 'val2',
]);
...就像调用:
DB::statement('INSERT INTO users (col1, col2) VALUES (val1, val2)');
它会 return 根据查询状态(是否插入内容)为您提供一个布尔值,但仅此而已。
因此:
User::insert($arr)->roles()->attach(Role::where('name', 'Student')); // Call to a member function roles() on boolean
// because insert() returns a boolean it's like writing
true->roles()->attach(Role::where('name', 'Student')); // Call to a member function roles() on boolean
您在当前问题之后会立即遇到的代码中的另一个问题是 ->roles()->attach(Role::where('name', 'Student'))
将不起作用,因为 attach()
需要模型实例、id 或 id 数组。这里你给了一个查询构建器(Role::where('name', 'Student')
),你需要附加->first()
.