我有一种方法可以将文件上传到一个表,然后使用Laravel的sync()
方法将这些文件链接到给定的模型。
目前,我在EventController
中有一个方法,该方法用于通过数据透视表将文件链接到事件。
该方法的路由如下:
Route::post('events/{event}/files/add', 'Editable\EventController@attachFiles');
方法如下:
/**
* Handle the attaching of a file to an Event
* Gets the files uploaded and adds them to the Template Library
* After this the files are associated with an Event
*
* @return void
*/
public function attachFiles(Request $request, Event $event)
{
$this->validate($request, [
'files.*' => 'sometimes|file|mimes:pdf|max:50000'
]);
// Initialize a file upload counter
$fileCount = 0;
// Initialize an empty array
$filenameArray = [];
// Ensure that the request contains files
if ($request->hasfile('files')) {
$files = $request->file('files');
$category = 'Post Event Documents';
// Loop through each file and add it to storage
foreach ($files as $file) {
// Get the meta data for each file
$name = $file->getClientOriginalName();
$extension = strtolower($file->getClientOriginalExtension());
$type = 'document';
$size = $file->getSize();
$path = $file->storeAs('library/' . $category . '/' . $event->id, $name);
// Create the database entries for the newly uploaded files
FileMetaData::firstOrCreate(
[
'name' => $name,
'extension' => $extension
],
[
'category' => $category,
'type' => $type,
'size' => $size,
'filepath' => $path
]);
$fileCount++;
$filenameArray[] = $name;
}
$files = FileMetaData::whereIn('name', $filenameArray)->get()->pluck('id');
$event->files()->syncWithoutDetaching($files);
return back()->with('success', $fileCount . ' files added to this Event');
return redirect()->back();
}
}
我想将此功能移到另一个控制器中,该控制器处理我当前所有的文件上传,但是要使用sync()
,您需要能够传递模型类型。
此刻,我在TemplateController
中用一种完全相同的方法玩弄:
public function uploadAndSync(Request $request)
{
// Get every extension that we allowed
$all_ext = implode(',', $this->allExtensions());
$this->validate($request, [
'files.*' => 'required|file|mimes:' . $all_ext . '|max:50000'
]);
// Initialize a file upload counter
$fileCount = 0;
// Initialize an empty array
$filenameArray = [];
// Get the category and department from the form
$category = $request->get('category');
// Ensure that the request contains files
if ($request->hasfile('files')) {
// Loop through each file and add it to storage
foreach ($request->file('files') as $file) {
// Get the meta data for each file
$name = $file->getClientOriginalName();
$extension = strtolower($file->getClientOriginalExtension());
$type = $this->getType($extension);
$size = $file->getSize();
// Upload all the given files to Storage, within a specific directory
if ($category != '') {
$path = $file->storeAs('library/' . $category, $name);
$department = null;
}
// Grab the filepath so we can store it in the database
$file->filepath = $path;
// Create the database entries for the newly uploaded files
FileMetaData::firstOrCreate(
[
'name' => $name,
'extension' => $extension
],
[
'category' => $category,
'type' => $type,
'size' => $size,
'filepath' => $path
]);
$fileCount++;
$filenameArray[] = $name;
}
$files = FileMetaData::whereIn('name', $filenameArray)->get()->pluck('id');
$event->files()->syncWithoutDetaching($files);
return back()->with('success', $fileCount . ' files added to this Event');
return redirect()->back();
}
}
但是,除了$event
之外,还有一种方法可以推断出文件应该与哪个模型同步?
因此在routes/web.php
中会有点像这样:
Route::post('upload/{model}/files/add', 'Editable\TemplateController@uploadAndSync');
这样我就不需要每个Controller中的一种方法来处理同步文件。
在我的Event
模型中,我定义了与文件的关系。
/**
* Get the files attached to this Event
*
* @return void
*/
public function files()
{
return $this->morphToMany(FileMetaData::class, 'attachable');
}
这是数据透视表: