when I update user data, show me error Call to a member function getKeyName() on string. I don't know why this error is. I will gratefull if someone help me resolve this.
model
class Customer extends Model
{
use HasFactory;
protected $fillable = [
'first_name',
'last_name',
'email',
'phone_number'
];
public function getRouteKeyName()
{
return 'id';
}
}
controller
public function update(CustomerRequest $request)
{
Customer::updated($request->validated());
return redirect()->route('customers.index')->with('updateMessage', 'Customer data successfully updated');
}
you should use the update method instead updated, the updated method is one of the model events in laravel, and when you update an instance of the model, the updated method run after that.
Related
Fiddling with Laravel and coming from Symfony, I'm trying to replicate some code.
I'm trying to PUT a Suggestion model (overwritting anything, even relationships) and wanted to know the proper way to overwrite the model.
Since tags attribute in fillable doesn't exist, I certainly get an error (Undefined column: 7 ERROR: column "tags" of relation "suggestions" does not exist).
Suggestions and tags both have their own tables and a pivot table that contains two foreign keys to both tables id.
Request & Response :
{
"id":2,
"content":"Magni.",
"tags":[{"id":13,"name":"MediumAquaMarine"}]
}
{
"id":2,
"content":"Magni.",
"tags":[{"id":10,"name":"Navy"},{"id":13,"name":"MediumAquaMarine"}]
}
public function update(Request $request, Suggestion $suggestion)
{
$validator = Validator::make($request->all(), [
'content' => 'required',
'tags.id' => 'numeric',
]);
if ($validator->fails()) {
return response()->json($validator->messages(), Response::HTTP_BAD_REQUEST);
}
$suggestion->fill($request->only($suggestion->getFillable()))->save();
return new SuggestionResource($suggestion);
}
class Suggestion extends Model
{
use HasFactory;
protected $fillable = ['content', 'tags'];
protected $with = ['tags'];
public function tags()
{
return $this->belongsToMany(Tag::class, 'suggestions_tags')->withTimestamps();
}
}
class Tag extends Model
{
use HasFactory;
protected $hidden = ['pivot'];
public function suggestions()
{
return $this->belongsToMany(Suggestion::class, 'suggestions_tags')->withTimestamps();
}
}
You could just pass an array of IDs for tags instead of the whole object.
Do:
"tags":[10, 13]
Instead of:
"tags":[{"id":10,"name":"Navy"},{"id":13,"name":"MediumAquaMarine"}]
Change the validation rules accordingly and then you can remove tags from $fillable and do something like:
$suggestion->update($request->validated());
$suggestion->tags()->sync($request->tags);
I have an Order model like this :
class Order extends Model
{
protected $primaryKey = 'order_id';
protected $fillable = ['desc', 'date_at', 'status'];
public function creator()
{
return $this->belongsTo(\App\User::class, 'creator', 'user_id');
}
public function validator()
{
return $this->belongsTo(\App\User::class, 'validator', 'user_id');
}
}
In the fields list there is a validator that can be set after creation of an instance of Order model Or not initialized at all.
Since validatior is nullable whenever I want to return an order I got an error like this :
Undefined property: Modules\\Order\\Entities\\Order::$validator
I believe your problem is with the name of the validator function since I assume is a key word in Laravel, try changing the name of the function to something else. and do a composer dump-autoload just in case
TL;DR
Trying to get three models to interact using eloquent for a rest api.
User - belongsToMany(pulls)
Pull - belongsToMany(user) && belongsToMany(boxes)
Box - belongsToMany(pulls)
The pull_user table is working perfectly, I can just attach a user after I save a pull. Saving a box works fine but the attach doesn't work/enter anything into the pivot table (I get no errors though).
The Problem
I can't get a pivot table that associates two of my models together to attach() after a save. I have the three models listed above, the pivot is working for pull_user but not for pull_box even though the save for box is working perfectly. I am able to save a box without an error but the association just never occurs (no error).
The Code
pull_box.php
class PullBox extends Migration
{
public function up()
{
Schema::create('pull_box', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('pull_id');
$table->integer('box_id');
});
}
public function down()
{
Schema::dropIfExists('pull_box');
}
}
Pull.php
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box');
}
}
Box.php
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull');
}
}
BoxController.php
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
...
]);
$user_id = $request->input('user_id');
...
$box = new Box([
'user_id' => $user_id,
...
]);
$pull = Pull::whereId($pull_id)->first();
if($box->save()){
$pull->boxes()->attach($box->id);
$box->view_box = [
'href' => 'api/v1/box/' . $box->id,
'method' => 'GET'
];
$message = [
'msg' => 'Box created',
'box' => $box,
'pull' => $pull_id
];
return response()->json($message, 201);
}
$response = [
'msg' => 'Box creation error, contact supervisor',
];
return response()->json($response, 404);
}
The Solution
I need to know how I can get this association working. I am going to need to add a new layer in under the pull for Item, but I don't want to move one before I solve this. I think that my problem has to stem from a syntactical/logical error on my part but I can't see it. There are a bunch of questions on SO that are very close to giving me a solution, but after reading them I wasn't able to solve my problem.
Any help is appreciated.
Try renaming your pull_box table to box_pull, pivot tables on laravel must be in alphabetical order. If you want to use custom name on pivot table you have to extends your pivot, for example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class PullBox extends Pivot
{
protected $table = 'pull_box';
}
And your many to many relationships:
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box')->using('App\PullBox');
}
}
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull')->using('App\PullBox');
}
}
I'm trying to create a resource provider database web app with a Resource, Location, ResourceLocation (pivot table), and ContactPerson models set up. I'm pretty sure I have the Model relationships set up correctly because from my Create A New Resource form it inserts the data into the database, it just doesn't show up in my view because the foreign keys (Resource_ID & Location_ID) aren't inserted into the pivot table. Here's the code I have so far.
Models
class Location extends Model
{
public function resource()
{
return $this->belongsToMany('App\Models\Resource', 'ResourceLocation');
}
}
class Resource extends Model
{
public function locations()
{
return $this->belongsToMany('App\Models\Location', 'ResourceLocation');
}
}
class ResourceLocation extends Model
{
protected $table = 'ResourceLocation';
public $timestamps = false;
protected $fillable = [
'Location_ID',
'Resource_ID'
];
}
Resource Controller
public function newResource(CreateNewResourceRequest $req)
{
$resource = Resource::create(Request::only(
'Name',
'Description',
'Misc_Info'
));
$location = Location::create(Request::only(
'Address',
'Address2',
'City',
'Zip_Code',
'County',
'Hours',
'Appt_Necessary'
));
$resource->save();
$resource->location()->attach($location);
\Session::flash('flash_message', 'Resource Created Successfully!');
return redirect('resource');
}
Once I hit the submit button on my form I get the error:
BadMethodCallException in Builder.php line 2345:
Call to undefined method Illuminate\Database\Query\Builder::location()
All the input from my form gets inserted into my database tables, but the ResourceLocation (pivot table) is left empty.
If I do $resource->$location()->attach($location['Location_ID']); it gives me a Method must be a string error. What am I doing wrong here? Any help would be greatly appreciated, thanks!
I figured it out, in my Resource Controller I have a location method:
public function location()
{
$locations = Location::all
return view (compact('locations'));
}
I changed my newResource method to:
public function newResource(CreateNewResourceRequest $req)
{
...
$resource->save();
$resource->locations()->attach($locations);
}
I wan't to get the name of the user who created is own thread. Like Michael did a thread about food. So at the bottom of the food-thread should be the name of Michael.
I've wrote the code for this but it doesn't really works. Maybe someone of you can find the mistake.
I have two models. A thread Model and a users model.
thread model:
<?php
namespace App\Models\Thread;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Thread extends Model {
public $table = 'thread';
public $fillable = [
'thread',
'content',
'user_id'
];
public function userthread() {
return $this->belongsTo('User','user_id', 'id');
user model:
<?php
namespace App;
use ...
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
public function threaduser() {
return $this->hasMany('App\Models\Thread\Thread','user_id', 'id');
}
}
and now the controller method, where I'm trying to get the name:
public function show($id)
{
$thread = Thread::query()->findOrFail($id);
$threaduser = Thread::where('user_id', Auth::user()->id)->with('userthread')->get();
return view('test.show', [
'thread' => $thread,
'threaduser' => $threaduser
]);
}
in my html:
{{$threaduser->name}}
The error message I get is :
Undefined property: Illuminate\Database\Eloquent\Collection::$name (View: /var/www/laravel/logs/resources/views/test/show.blade.php)
I hope someone can help me there.
change it to
{{$threaduser->userthread->name}}
change userthread() function in your Thread Class to
public function userthread() {
return $this->belongsTo('App\User','user_id', 'id');
}
get() gives you a Collection not a Model you either have to do a foreach on it like
#foreach ($threadusers as $threaduser)
{{ $threaduser->userthread->name }}
#endforeach
Or use first instead of get if there is only one Thread per User.
Depending on what you want to do, of course.