Two store() methods, one doesn't work (Call to undefined method save()) - laravel

One of two similar store methods doesn't work. Could you clarify this for me?
Relations
A Team hasMany Users <> A User belongsTo a Team
A User hasMany Characters <> A Character belongsTo a User
Working Code (CharacterController)
public function store()
{
$fighters = Fighter::pluck('name')->toArray();
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|not_in:'.Rule::notIn($fighters).'unique:characters',
'fighter' => 'required|in:'.Rule::in($fighters),
]);
auth()->user()->characters()->save(new Character([
'name' => request('name'),
'fighter' => request('fighter'),
]));
return redirect()->route('character.index');
}
Not Working (TeamController)
public function store()
{
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|unique:teams',
]);
auth()->user()->team()->save(new Team([
'name' => request('name'),
'fame' => 0,
]));
return redirect()->route('team.index');
}
Questions
Why is the same method not available? Is it relation stuff?
Is the create method better? Should I try to use it?
Thought I know what I'm doing, now it turns out I don't...
Thank you for helping.

team() is a belongsTo relation, you probably have a team_id col in your user table which you want to associate with the team.
public function store()
{
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|unique:teams',
]);
// create and save team
$team = new Team([
'name' => request('name'),
'fame' => 0,
]);
$team->save();
// associate current authenticated user with team (set foreign key) and save user
auth()->user()->team()->associate($team)->save();
return redirect()->route('team.index');
}

Related

How to upload file in relationship hasOn<->belongsTo Laravel Backpack

Can be possible to store a file uploaded to a related table?
Scenario: I have a usres table in database and another one pictures. Users Model have the following function
public function picture()
{
return $this->hasOne(Picture::class);
}
And the Picture Model have the following function.
public function user_picture()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
Is possible to store the picture in pictures database table (id, user_id, img_path) from the UserCrudController store() function?
try something like this
public function store(Request $request)
{
Picture::create([
'user_id' => // get the user id from $request or auth()->user(),
'img_path' => $request->file('image')->store('images', 'public'),
]);
return // your view or something else
}
Let's say it is a registration form that need to insert an image. Instead of using the Picture model directly you can just do this :
public function store(Request $request)
{
$request->validate(...);
$user = User::create(...);
//It will ensure that the image belongs to the user.
$user->picture()->create([
'image_path' => $request->file('image')->store('images');
])
}
I resolved the issue with the following steps.
As per Laravel Backpack I added the input field in the Blade:
#include('crud::fields.upload', ['crud' => $crud, 'field' => ['name' => 'img1', 'label' => 'Image 1', 'type' => 'upload', 'upload'=> true, 'disk'=>'uploads', 'attributes' => ['id' => 'img1', 'capture' => 'user']]])
After this I added the function in the User Controller as follow:
$request->validate(['img1' => 'mimes:jpg,png,jpeg|max:5120']);
$fileModel = new Picture;
if($request->file()) {
$fileName1 = time().'_'.$request->img1->getClientOriginalName();
$filePath1 = $request->file('img1')->storeAs('uploads', $fileName1, 'public');
$fileModel->name = time().'_'.$request->img1->getClientOriginalName();
$fileModel->img1 = '/storage/' . $filePath1;
$fileModel->save();
}
With these lines of code I was able to store the related Picture with the User.
Thank you all for the guidelines.

Property [user] does not exist on this collection instance

i'm developping a social app using React in the frontend and laravel in the backend.
I'm trying to receive all posts with their likes,users,comments. I have these relation ships:
1/ User model has many posts and Post model belongs to a user.
2/ Post model has many likes
3/ Post model has many comments and one comment belongs to a user.
When getting all posts back, im succefully getting its likes and users information, but for comments i wanna get the user's comment. So i did $posts->comments->user->user_name
And then, i got the error: Property [user] does not exist on this collection instance. But when i tried to get comments infos, it worked normally($posts->comments)
My comment relation in Post model:
public function comments()
{
return $this->hasMany('App\Models\Comment');
}
My user relation in Comment Model:
public function user()
{
return $this->belongsTo('App\Models\User');
}
My method in PostController when i'm trying to get all posts:
public function allPosts()
{
$posts = Post::with('user','likes','comments')->get();
if($posts->count() < 1) {
return response()->json([
'success' => false,
'message' => 'There are no posts!'
]);
}else {
return response()->json([
'success' => true,
'data' => PostResource::collection($posts),
'message' => 'Succefully retreived all posts!'
]);
}
}
As you noticed i'm sending the Data through a Resource, so My PostResource's method :
public function toArray($request)
{
// return parent::toArray($request);
return [
'id' => $this->id,
'user_id' => $this->user_id,
'content' => $this->content,
'image_path' => $this->image_path,
'user' => $this->user,
'likes' => $this->likes->count(),
'isLiked' => $this->likes->where('user_id', auth()->user()->id)->isEmpty() ? false : true,
'comment_user' => $this->comments->user->user_name,
'created_at' => $this->created_at->format('d/m/y'),
'updated_at' => $this->updated_at->format('d/m/y')
];
}
As i said, everything is okey, just for comment_user it says:Property [user] does not exist on this collection instance, and when i tried to get only comments info it worked:
'comments' => $this->comments,
Any help please? and thnx in advance.
Maybe you need to add relation user() to Post model?

Creating two relationships from the same controller method in laravel

I am trying to allow users to post pictures and comment on pictures. The pictures are related to the users through a one to many relationship and the comments are related to the pictures through a one to many relationship. I am now trying to simultaneously relate both users and pictures to comments whenever a comment is made. Currently, I am able to relate comments to either the picture or the user but not both.
Below is the controller method which handles comment uploads:
public function postComment(Request $request, $picture_id)
{
$this->validate($request, [
"comment" => ['required', 'max:1000'],
]);
$picture = Picture::find($picture_id);
$picture->status()->create([
'body' => $request->input('comment'),
]);
Auth::user()->statuses()->update([
'body' => $request->input('comment'),
]);
return redirect()->back();
}
I have tried creating one relationship and then creating the other relationship using update(). This did not work and resulted in the value remaining null.
Thank you for your help.
If i am understanding your database model correctly, when creating the status model for your picture all you need to do is to also include the user id like so:
public function postComment(Request $request, $picture_id)
{
$this->validate($request, [
"comment" => ['required', 'max:1000'],
]);
$picture = Picture::find($picture_id);
$picture->status()->create([
'body' => $request->input('comment'),
'user_id' => Auth::id()
]);
return redirect()->back();
}
Also make sure to add user_id to the $fillable property in the Status model to allow it to be assigned through the create method
protected $fillable = [
'body', 'user_id',
];
This should link the status you just created to both the picture and user class. You can then retrieve it elsewhere with something like Auth::user()->statuses

Need help about passing club_id in player controller

I'm making football blog and I want to make that i can create players, but i have problem with it because i get eroor "Call to a member function players() on null" i know where is problem but i dont know how to solve it, I have similar problem with comments and posts but i done it and now again same problem but it dont work
//PlayersController
public function store(Request $request)
{
$this->validate($request, [
'fname' => 'required',
'lname' => 'required',
'age' => 'required',
'country' => 'required',
'position' => 'required',
'image' => 'image|nullable|max:1999',
'text' => 'required'
]);
//create Player
$player = new Player;
$player->fname = $request->input('fname');
$player->lname = $request->input('lname');
$player->age = $request->input('age');
$player->country = $request->input('country');
$player->position = $request->input('position');
$player->image = $fileNameToStore;
$player->text = $request->input('text');
$club = Club::find($request->get('club_id')); //problem
$club->players()->save($player); //problem
}
//club model
public function players()
{
return $this->hasMany(Player::class);
}
//player model
public function club()
{
return $this->belongsTo(Club::class);
}
Sounds like $club is coming back null and that's why Laravel is giving an error when you try to use players() on it. Have you checked that $request->get('club_id') is giving you what you expect?
Also don't forget that your new $player doesn't fully exist yet in the database until you do $player->save(). Not sure if you can save it and also create its relationship to $club in one line. You could try saving it first, and then attaching it.

Right way to handle this situation using Laravel validation

i am new in Laravel and I would like to have some directive on how to handle this situation.
I have two entities: Ad and Nomination. Ad can have many Nominations.
In a controller i receive two external inputs: [ad_id] and [nomination_id] both required.
What i have to do with these two inputs is:
Check if [ad_id] is an existing Ad entity and his attribute "active" is true.
Check [nomination_id] is an existing Nomination entity.
Only if [ad_id] was an existing Ad and [nomination_id] was an existing Nomination check if this Nomination belongs to this Ad.
Can you show me an example about how to manage this using only validation class?
You can write your validation rules like this
public function rules()
{
return [
'ad_id' => [
'bail',
'required',
Rule::exists('ads')->where(function ($query) use ($request) {
$query->where([
['active' => 1],
['id' => $request->ad_id]
]);
}),
],
'nomination_id' => [
'bail',
'required',
Rule::exists('nominations')->where(function ($query) use ($request) {
$query->where([
['ad_id' => $request->ad_id],
['id' => $request->nomination_id]
]);
}),
],
];
}
Assuming you have ads and nominations are tables name and primary key field is id and ad_id as foreign key in nominations table.
It's pretty straightforward - you can write validation rules just as you listed them in your question:
$validator = Validator::make($request->only('ad_id', 'nomination_id'), [
'ad_id' => 'required|exists:ads,id,active,1',
'nomination_id' => 'required|exists:nominations,id,ad_id,' . $request->ad_id,
]);
if ($validator->fails()) {
...
}
$inputAd = <some_value>;
$inputNomination = <some_value>;
$nomination = Nomination::where(['id' => $inputNomination])->with(['ads'])->first();
if(!$nomination || !($nomination->ad_id == $inputAd)) {
// not the same
}
// same
To validate the ad_id and nomination_id, you can use laravel in rule.
FormRequest Class
public function rules()
{
return [
'ad_id' => [
'required',
Rule::in(Ad::where('active', true)->pluck('id')->toArray()),
],
'nomination_id' => [
'required',
Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()),
],
];
}
The Rule::in(Ad::where('active', true)->pluck('id')->toArray()), rule will check if the ad_id is present in the array of ids of Ad which have active field is true.
The Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()), rule will check if the nomination_id is present in the array of ids of Nomination which is related to Ad.

Resources