I am pretty newbie for Laravel 5 and I am building an file gallery with tagging system. I am using Laravel 5.5 and each file has tags. I have created file table and tags table as well as file_tag pivot table. I am using Select2 for tag selection and creation on front end input. When I add tags and if the tags don't exist for that file, it works perfectly. But when I try to tag existing tags on file creation, it only passes existing tags' tag_id as name.
My goal is if the tags don't exist create the tags and create file tag relationship, if the tags exist already, just the create file tag relationship.
This is how I pass tags in form in my upload.blade.php form:
<select name="tags[]" class="form-control select2-multi-tags" multiple="multiple">
@foreach($tags as $tag)
<option value="{{$tag->id}}">{{$tag->name}}</option>
@endforeach
</select>
These are my tables for tags and file_tag pivot:
Tags:
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string( 'name' );
$table->timestamps();
});
}
file_tag pivot table:
public function up()
{
Schema::create('file_tag', function (Blueprint $table) {
$table->increments('id');
$table->integer('file_id')->unsigned()->index();
$table->foreign( 'file_id' )->references( 'id' )->on( 'files' )->onDelete( 'cascade' );
$table->integer( 'tag_id' )->unsigned()->index();
$table->foreign( 'tag_id' )->references( 'id' )->on( 'tags' )->onDelete( 'cascade' );
});
}
Tag Model:
class Tag extends Model
{
protected $table = 'tags';
protected $fillable = [ 'name'];
public function files()
{
return $this->belongsToMany( '\App\File');
}
}
File Model
class File extends Model
{
protected $table = 'files';
public function tags()
{
return $this->belongsToMany( '\App\Tag');
}
}
My store controller
public function storeFile( request $request )
{
if ( $request->hasFile( 'file' ) )
{
$image = $request->file( 'file' );
$thumbnail_name = pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME).'_thumb_'.time().'.'.$image->getClientOriginalExtension();
$path = 'thumbnails/'.$thumbnail_name;
Image::make( $image->getRealPath() )->resize( 640, 400 )->save( $path );
//Get filename with extension
$filenameWithExt = $image->getClientOriginalName();
//Get just the file name
$filename = pathinfo( $filenameWithExt, PATHINFO_FILENAME );
//Get the extension
$extension = $image->getClientOriginalExtension();
//Create new filename
$filenameToStore = $filename . '_' . time() . '.' . $extension;
//Upload image
$fileStore = $image->storeAs( 'public/images', $filenameToStore );
$fileSize = $image->getClientSize();
$fileTitle = $request->title;
$fileModel = new File;
$fileModel->title = $fileTitle;
$fileModel->name = $filenameToStore;
$fileModel->thumbnail_name = $thumbnail_name;
$fileModel->size = $fileSize;
$fileModel->save();
$tags = $request->tags;
$tagIds = [];
foreach ($tags as $tagName)
{
$tag = Tag::firstOrCreate(['name'=>$tagName]);
if($tag)
{
$tagIds[] = $tag->id;
}
}
$fileModel->tags()->syncWithoutDetaching($tagIds);
return redirect('/upload')->with('success', 'Image/Images created.');
}
}
I am not sure what I am doing wrong or what I need to do in order to accomplish the goal. Any help would be appreciated.
Thanks for your time and attention.