Closed unarmedwombat closed 5 years ago
Hi @unarmedwombat , could you provide your code?
Here is the Nova controller fields method:
public function fields(Request $request)
{
$categories = Category::all()->pluck('full_name', 'id');
return [
ID::make()->hideFromIndex(),
Text::make('Code')
->sortable()
->creationRules(['required', 'unique:products,code', 'max:255'])
->updateRules(['required', 'max:255']),
Text::make('Name')
->sortable()
->rules(['required', 'max:255']),
Trix::make('description'),
Select2::make('Categories', 'categoryList')
->hideWhenCreating()
->options($categories)
->configuration([
'allowClear' => true,
'minimumResultsForSearch' => 1,
'multiple' => true,
'placeholder' => 'Choose one or more categories',
]),
new Panel('Images', $this->imagesPanel()),
new Panel('Visibility', $this->displayPanel()),
new Panel('Other data', $this->otherPanel()),
];
}
And the Categories model:
class Category extends Model implements HasMedia, Sortable { use HasMediaTrait, SortableTrait;
protected $appends = ['full_name'];
public $sortable = [
'order_column_name' => 'order',
'sort_when_creating' => true,
];
public function registerMediaCollections()
{
$this->addMediaCollection('main_image')
->singleFile();
}
public function registerMediaConversions(Media $media = null)
{
$this->addMediaConversion('thumb')
->fit(Manipulations::FIT_CONTAIN, 250, 250);
}
public function section()
{
return $this->belongsTo(Section::class);
}
public function products()
{
return $this->belongsToMany(Product::class)
->withTimestamps();
}
public function getFullNameAttribute()
{
$section = Section::find($this->attributes['section_id'])->name;
return $section . " - " . $this->attributes['name'];
}
} Hope this is what you need, if not, let me know. Thanks.
Sorry , meant to include the product model:
class Product extends Model implements HasMedia {
use HasMediaTrait;
public function registerMediaCollections()
{
$this->addMediaCollection('main_image')
->singleFile();
$this->addMediaCollection('other_images');
$this->addMediaCollection('documents');
}
public function registerMediaConversions(Media $media = null)
{
$this->addMediaConversion('thumb')
->fit(Manipulations::FIT_CONTAIN, 150, 150);
$this->addMediaConversion('display')
->fit(Manipulations::FIT_CONTAIN, 500, 500);
}
public function material() {
return $this->belongsTo(Material::class); }
public function categories() {
return $this->belongsToMany(Category::class)
->withTimestamps();
}
public function related_to() {
return $this->belongsToMany(Product::class, 'product_related', 'product_id', 'related_id')
->withTimestamps();
}
public function details() {
return $this->belongsToMany(DetailTitle::class, 'details')
->withPivot('content')
->withTimestamps()
->as('detail');
}
public function getCategoryListAttribute()
{
return $this->categories->pluck('id')->all();
}
public function setCategoryListAttribute($value)
{
$categories = explode(",", $value);
$this->categories()->sync($categories);
}
}
Hi @unarmedwombat , i think problem on your relations, i tryed reproduce it in my side and i have all fine. You can try replace Select2 to native Select component or remove Select2 component from fields method and try create new product.
Hi @unarmedwombat , i'm double investigated in your issue and solve it! :)
public function setCategoryListAttribute($value)
hideWhenCreating()
method on your Select2
fieldpublic static function boot()
{
parent::boot();
static::created(function ($model) {
$items = explode(',', request('categoryList'));
$model->categories()->sync($items);
});
static::updated(function ($model) {
$items = explode(',', request('categoryList'));
$model->categories()->sync($items);
});
}
on your Product
model
I have a very similar problem to above but making the changes do not seem to work for me so I would really appreciate assistance.
I can update existing 'workorders' without issue apart from when I remove all engineers I get the following error.
If I try to create a new 'workorder', I get the following error if I have engineers selected.
If I try to create a new 'workorder', I get the following error if I have no engineers selected.
App\WorkOrder.php `<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Mail; use Carbon\Carbon; use App\Mail\WorkorderProfile;
class WorkOrder extends Model {
protected static function boot()
{
parent::boot();
/*static::saving(function ($workorder) {
});*/
}
protected $fillable = [
'system_id',
'body',
'requirements',
'date',
];
protected $casts = [
'date' => 'datetime'
];
public function system()
{
return $this->belongsTo('App\System');
}
public function engineers()
{
return $this->belongsToMany(__NAMESPACE__.'\\User', 'workorder_engineer', 'workorder_id', 'engineer_id');
}
public function getEngineerListAttribute()
{
return $this->engineers->pluck('id')->all();
}
public function setEngineerListAttribute($value)
{
$engineers = explode(",", $value);
$this->engineers()->sync($engineers);
}
}
App\Nova\WorkOrder
<?php
namespace App\Nova;
use Laravel\Nova\Fields\ID; use Illuminate\Http\Request; use Laravel\Nova\Http\Requests\NovaRequest; use Laravel\Nova\Fields\BelongsTo; use Laravel\Nova\Fields\BelongsToMany; use Laravel\Nova\Fields\Textarea; use Laravel\Nova\Fields\DateTime; use App\User; use Koss\LaravelNovaSelect2\Select2;
class WorkOrder extends Resource { /**
@var string */ public static $model = 'App\WorkOrder';
/**
@var string */ public static $title = 'id';
/**
@var array */ public static $search = [ 'id', ];
public static function label() { return 'Work Orders'; }
/**
@return array */ public function fields(Request $request) { $engineers = User::all()->pluck('name', 'id');
return [
ID::make()->sortable(),
BelongsTo::make('System')
->sortable()
->rules('required')
->searchable(),
DateTime::make('Date')->hideFromIndex(),
Textarea::make('Body')->alwaysShow(),
Textarea::make('Requirements')->alwaysShow(),
Select2::make('Engineers', 'engineerList')
->sortable()
->options($engineers)
/**
* Documentation
* https://select2.org/configuration/options-api
*/
->configuration([
'placeholder' => __('Choose options'),
'allowClear' => true,
'minimumResultsForSearch' => 1,
'multiple' => true,
]),
];
}
/**
@return array */ public function cards(Request $request) { return []; }
/**
@return array */ public function filters(Request $request) { return []; }
/**
@return array */ public function lenses(Request $request) { return []; }
/**
I have a product model which can belong to one or more categories (many to many). I'm using select2 with the multiple option, but when I try to create a new product it responds with an integrity violation on the category_product model, saying the product_id can't be null. Looking at the trace, it appears to be trying to sync the category link before it stores the new product record? The field works fine on update, its just creating that has the problem. It's possible I've missed something, but I think I've tried the example code exactly as in the read.me