Laravel Nova nested relation - php

Recently I've been trying to create Nova resource which depends on the other resource which provides the information for the main resource.
I have a table contest_entries which has the following fields:
id
contest_id
user_id
with the following relations
public function contest() : BelongsTo {
return $this->belongsTo(Contest::class, 'contest_id', 'id');
}
public function user() : BelongsTo {
return $this->belongsTo(User::class, 'user_id', 'id');
}
Also, i have a table contest_submissions with the following fields:
id
entry_id
task_id
comment
approved
declined
with the following relations:
public function entry() : BelongsTo {
return $this->belongsTo(ContestEntry::class, 'entry_id', 'id');
}
public function user() : BelongsTo {
return $this->entry->user();
}
public function contest() : BelongsTo {
return $this->entry->contest();
}
public function task() : BelongsTo {
return $this->belongsTo(Task::class, 'task_id', 'id');
}
I have no problem in fetching this data on the index and details view of Nova, everything 'just works', however, when I try to update the resource, I'm getting the error that user() or contest() is called on null.
I've tried the following,
return [
BelongsTo::make('Contest', 'contest', Contests::class)->exceptOnForms(),
BelongsTo::make('Task', 'task', ContestTasks::class)->exceptOnForms(),
BelongsTo::make('User', 'user', AccountUsers::class)->exceptOnForms(),
]
But for some reason, Nova is still trying to fetch these relationships ever when i explicitly tell it not to.
Any ideas are greatly appreciated, because it works everywhere, except on the update view (create view is explicitly disabled since the submissions are created by the user on the frontend)

You should also chain a hideWhenUpdating() constraint to it.
return [
BelongsTo::make('Contest', 'contest', Contests::class)
->hideWhenUpdating()
->exceptOnForms(),
BelongsTo::make('Task', 'task', ContestTasks::class)
->hideWhenUpdating()
->exceptOnForms(),
BelongsTo::make('User', 'user', AccountUsers::class)
->hideWhenUpdating()
->exceptOnForms(),
]

Related

Laravel Relationship not cascading to hasMany

I have 2 models, 'Tickets' and 'Messages', user can have many tickets and each ticket many messages.
class Message extends Model {
public function Ticket() {
return $this->belongsTo(Ticket::class, 'ticket_id', 'ticket_id');
}
public function user() {
return $this->belongsTo(User::class, 'user_id', 'user_id');
}
}
class Ticket extends Model {
public function messages() {
return $this->hasMany(Message::class, 'ticket_id', 'ticket_id');
}
public function user() {
return $this->belongsTo(User::class, 'user_id', 'user_id');
}
}
When trying to create a message attached to current user via the below code:
$Ticket->messages()->create([
'message' => $post['message']
]);
I get the following error:
Cannot insert the value NULL into column 'user_id', table 'messages'
Since Ticket is already linked to a user, I assumed it's going to cascade to message as well. I can manually specify it but I want everything to be built using laravel relationships the most correct way

relationship laravel empty result

I´m traying create relation ship in my model user-roles.
Firt i have to say that i´m using Bouncer library to use permission and roles.
I have my model User with this realation:
public function roles()
{
return $this->belongsTo('App\AssignedRoles', 'entity_id');
}
and my model AssignedRole:
public function user()
{
return $this->hasMany('App\User', 'id', 'entity_id');
}
and
public function roleName()
{
return $this->belongsTo('App\Role', 'id', 'role_id');
}
in my controller i´m trayin return all role that it has one User, using this:
$employee = User::with('roles')->get();
but return this:
Array([roles] => )
what i´m doing wrong?
I need create user list with his roles.
Thanks for read and sorry for my english

Laravel relationship doesn't return data

I am trying to get my data in table by ajax and it's successfull but some of data are id of other tabels and those data i cannot get somehow!
Example
Sample data returned by JS:
customers":[
{
"id":2,
"group_id":3,
"industry_id":2,
"name":"fwgvwrg",
"companyName":"bget"
}
]
In this data if i use like: i.group.name (same as in blade if we say {{$customer->group->name}} for group_id it returns error of
Uncaught TypeError: Cannot read property 'name' of undefined
Basically there is no issue from JS it's about my models relations here are my models:
Customer model
public function group()
{
return $this->belongsTo(GroupCustomer::class, 'id', 'group_id');
}
public function industry()
{
return $this->belongsTo(Industry::class);
}
Groups model
public function customers() {
return $this->hasMany(Customer::class, 'id', 'group_id');
}
Industry model
public function customers() {
return $this->hasMany(Customer::class);
}
Any idea?
Seems the problem is your model relationship about foreign key parameter position:
public function group()
{
return $this->belongsTo(GroupCustomer::class, 'group_id', 'id');
}
See model doc here
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
In Blade view you can call laravel relationship directly. it will work fine.
but in Js it won't work. you can't call relationship
so when you have to use with() like below
Ex : Customer::with('group')->get();

Laravel Nova Self-referential Relationship

In Laravel, if I want to create a self-referential relationship I can do the following:
class Post extends Eloquent
{
public function parent()
{
return $this->belongsTo('Post', 'parent_id');
}
public function children()
{
return $this->hasMany('Post', 'parent_id');
}
}
How can I make a Laravel Nova resource display this connection?
public function fields(Request $request)
{
return [
Text::make('Autor', 'author'),
Select::make('Type', 'type')->options([
'News' => 'news',
'Update' => 'update',
]),
BelongsToMany::make('Post') // does not work
];
}
You can achieve what you want like this:
BelongsTo::make('Parent', 'parent', \App\Nova\Post::class),
HasMany::make('Children', 'children', \App\Nova\Post::class),
This will allow to choose a parent post when you create or update a post. When you are in the detail page of a post, you can see all its children.
public function fields(Request $request)
{
return [
Text::make('Author', 'author'),
Select::make('Type','type')->options([
'News' => 'news',
'Update' => 'update',
]),
BelongsTo::make('Parent', 'parent', \App\Nova\Post::class),
HasMany::make('Children', 'children', \App\Nova\Post::class),
];
}
Note: Please note that the third param to BelongsTo::make() and HasMany::make() is a reference to the Post Resource, not Post model.
There is another situation, where you will find same issue, if you have parent column name parent and also relationship parent like
$table->bigIncrements('id');
$table->string('category');
$table->unsignedBigInteger('parent')->nullable();
and
In model
public function parent()
{
return $this->belongsTo(SELF::class, 'parent');
}
It will be unable to recognize the parent property and you will face this problem again, in that case, you can change the relationship name or column name, and it will work fine.
Also remember the arguments for Nova BelongsTo relationship
Argument 1. Name to display (e.g. Parent)
Argument 2. Name of the relationship as used in the model (e.g. parent)
Argument 3. The Nova Resource (e.g. App\Nova\Category)

Eloquent relationship. Changed table name

I have users table with id on it.
My project model has $fillable fields:
protected $fillable = [
'title',
'description',
'visibility_level',
'creator_id'
];
relationship:
public function user()
{
return $this->belongsTo('App\User');
}
In Users model relationship:
public function projects()
{
return $this->hasMany('App\Project');
}
Now creator_id is refering to user_id. I have set up my project model table with:
$table->foreign('creator_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
But then I try to store data, it still tried to add user_id:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'field list'
My store() method:
public function store(ProjectRequest $request)
{
$project = new Project($request->all());
Auth::user()->projects()->save($project);
flash()->success('Project have been created');
return redirect('news/');
}
Am I searching In wrong place or what? I dont understand why its "user_id" where is this "user_id" generated name comes from?
The user_id key comes from the name of your class (User). All laravel does is snake case it and append _id to it. To fix your issue, use the second, optional, parameter for hasMany on your User class:
public function projects()
{
return $this->hasMany('App\Project', 'creator_id');
}
This should solve your problems now but, to use the relationship the other direction, you'll also need to make some changes on your Project model. You have two choices:
Rename your relationship method:
public function creator()
{
return $this->belongsTo('App\User');
}
Override the key by passing it as second parameter to belongsTo:
public function user()
{
return $this->belongsTo('App\User', 'creator_id');
}
Given what you are trying to achieve, I'd recommend you go with the first option.

Categories