Model not making it to controller - laravel

I am having some difficulties getting my Model to my controller. Now I do not know if this is an important point, but this system does not have a database per say. It uses an API I have built to insert its data into an external systems database. I had to design it this way for numorous reasons.
Anyways, I have my Models set up (even though they dont have their own database) and then my route is like so
Route::model('projects', 'Project');
Route::bind('projects', function($value, $route) {
return App\Project::whereId($value)->first();
});
Route::resource('projects', 'ProjectController');
Now everything I need to do works besides the update. Now I have an update form which opens like so
{!! Form::model($project, [
'class'=>'form-horizontal',
'method' => 'PATCH',
'route' => ['projects.update', $project->id]
]) !!}
If I output $project I see what I expect to see. This calls my update function which is currently like this
public function update(Request $request, Project $project)
{
dd($project);
}
The $request object is fine, I can see all the inputs. However, $project is empty. Am I missing something obvious here or do I need a table for this to work?
Any information appreciated.
Thanks

Related

$page.props.user it works but $page.props.user.name doesn't work

I made an application using vue laravel and inertia, I'm trying to feed my application through the $page that inertia makes available, when I went to test in the console.log the $page.props.user works normally showing the array with all the data, but how much I try to call a property of the base, for example the name, I put $page.props.user.name it gives undefined, if you can help me thank you.
mounted(){
console.log(this.$page.props.user)
console.log(this.$page.props.user.name)
};
Controller:
public function home(){
$user = User::all();
return Inertia::render('Home', [ 'user' => $user]);
}
$user = User::all();
This query returns all users as an array (a Laravel collection in fact). So the view will obviously receive an array as well.
You likely need Auth::user() (using the Auth facade) or whatever equivalent you have to retrieve the currently logged in user.

Where to save different models at once in Laravel?

I have a litte question for you.
I'm using Laravel and I'm not sure which is the best way (and place) to save different models at same time.
For example:
When a user creates a "RecordSheet", I need to automatically create other models related to the RecordSheet model. Obviously I will create the RecordSheet model in his own controller:
class RecordSheetController extends Controller
{
public function store(){
RecordSheet::create([
.......
'user_id' => Auth::user()->id
]);
}
}
Where should I put the creation of the other models? In the same RecordSheetController?
class RecordSheetController extends Controller
{
public function store(){
DB:beginTranaction()
try{
$record = RecordSheet::create([
.......
'user_id' => Auth::user()->id
]);
ModelB::create([
.......
'recordSheet' => $record->id,
'user_id' => Auth::user()->id
]);
}catch(Exception $e)
{
DB:rollback();
}
DB:committ();
}
}
I'm not sure about thate since I suppose that RecordSheetController should be responsible only of "RecordSheet" models and not other models.
Any suggestion would be appreciated! Thanks everyone!
you can use Laravel Observers for this scenario, create a RecordSheetObserver and place your ModelB code in the created method
Laravel provides some built-in conventions for placement of your action or CRUD (Create - Read - Update - Delete) code.
Typically, you can put the related model action in the same method. To start, you can utilise the artisan command:
php artisan make:controller RecordSheetController --resource
This will add the standard methods to your controller. These methods tie into any resource methods you have in your routing, which follow standards for GET/POST/PUT/etc.
Once you have your controller set up, it is usually easiest and most readable to do your related action within the same method, so you don't have to go back and forth with the user from page to controller and back again. So:
public function store(Request $request){
// Add transactions as you wish
$record = RecordSheet::create([
.......
' user_id' => Auth::user()->id
]);
ModelB::create([
.......
'recordSheet' => $record->id,
'user_id' => Auth::user()->id
]);
}
You can certainly make sub functions within this, but the key is to perform this at one time for efficiency. If there are many repeatable sub functions with less related actions, it may be helpful to move this to other parts of your app. But for simple, directly related creation, it tends to be more readable to keep them in the same class.

How does Laravel generate SQL?

I'm brand new to Laravel and am working my way through the Laravel 6 from Scratch course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.
I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that. Now I'm trying to add two new fields: an author name and a path to a picture illustrating the article. I've updated the migration, rolled back and rerun the migration to include the new fields and got no errors from that. (I also ran a migrate:free and got no errors from that.) I've also updated the forms used to create and update the articles and added validations for the new fields. However, when I go to execute the revised create code, it fails because the SQL is wrong.
The error message complains that the author field doesn't have a default, which is true, I didn't assign a default. However, I did give it a value on the form. What perplexes me most is the SQL that it has generated: the column list doesn't show the two new columns. And that's not all: the values list is missing apostrophes around any of the string/text values. (All of the columns are defined as string or text.)
As I said, I'm completely new to Laravel so I don't know how to persuade Laravel to add the two new columns to the Insert statement nor how to make it put apostrophes around the strings in the values list. That hasn't come up in the course and I'm not sure if it will come up later. I was hoping someone could tell me how to fix this. All of my functionality was working fine before I added the two new fields/columns.
Here is the error message:
SQLSTATE[HY000]: General error: 1364 Field 'author' doesn't have a default value (SQL: insert into `articles` (`title`, `excerpt`, `body`, `updated_at`, `created_at`) values (Today in Canada, The ideal winter-beater, This car is the ideal winter-beater for the tough Canadian climate. It is designed to get you from A to B in style and without breaking the bank., 2020-02-15 17:37:54, 2020-02-15 17:37:54))
Here is ArticlesController:
<?php
namespace App\Http\Controllers;
use App\Article;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index()
{
$articles = Article::latest()->get();
return view ('articles.index', ['articles' => $articles]);
}
public function show(Article $article)
{
return view('articles.show', ['article' => $article]);
}
public function create()
{
return view('articles.create');
}
public function store()
{
//Stores a NEW article
Article::create($this->validateArticle());
return redirect('/articles');
}
public function edit(Article $article)
{
return view('articles.edit', ['article' => $article]);
}
public function update(Article $article)
{
//Updates an EXISTING article
$article->update($this->validateArticle());
return redirect('/articles/', $article->id);
}
public function validateArticle()
{
return request()->validate([
'title' => ['required', 'min:5', 'max:20'],
'author' => ['required', 'min:5', 'max:30'],
'photopath' => ['required', 'min:10', 'max:100'],
'excerpt' => ['required', 'min:10', 'max:50'],
'body' => ['required', 'min:50', 'max:500']
]);
}
public function destroy(Article $article)
{
//Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
//If user chooses Delete, delete the record
//If user chooses Cancel, return to the list of articles
}
}
Is there anything else you need to see?
It may be possible because of you don't have defined that column in fillable property, to use mass assignment you have to specify that columns.
Try after adding that columns in fillable property.
Laravel mass assignment
Hope this helps :)

Laravel 5.4 storing mass assignment model and relationship

I'm unsure of the best practice when inserting mass assignment relationships within Laravel 5.4 - I'm new to the framework. The below code is working correctly, however can you tell me is there a way to simply into one line (inserting relationships)?
I've tried to look at 'save()'and 'push()' but it's not working as expected. Would this have an impact if transactions would scale up?
I have a Listing model, with a hasOne relationship:
public function garage()
{
return $this->hasOne('App\Garage', 'post_id');
}
First of all I have some validation, then I use the following to store, which I want to simplify to one one line of code:
public function store(Request $request)
{
// Validation has passed, insert data into database
$listing = Listing::create($request->all());
$listing->Garage()->create($request->all());
}
Also if I wanted to return the data inserted, how would I do this as the following is only returning the Listing model and not the Garage relationship? Yes I know that I wouldn't do this in a real world application.
return \Response::json([
'message' => 'Post Created Succesfully',
'data' => $listing
]);
Any help is muchly appreciated
Method chaining
Your store method looks good. You could chain methods though, if you don't need the listing object itself:
public function store(Request $request)
{
// Validation has passed, insert data into database
$garage = Listing::create($request->all())
->garage()->create($request->all();
}
But if you need the listing object, it's fine as you did it before!
Returning relation models
If you want to return the garage relation model too, you can simply do that by accessing it like a normal class propery:
return \Response::json([
'message' => 'Post Created Succesfully',
'data' => [$listing, $listing->garage]
//Access collection of garage relation ship
]);

Simplify store controller method on laravel 5

This is my store method to save a post.
public function store(CreatePostRequest $request)
{
$post = new Post([
'title' => $request['title'],
'content' => Crypt::encrypt($request['content']),
'published_at' => Carbon::now()
]);
$post->user()->associate(Auth::user());
$newPost=Post::create($post->toArray());
$this->syncTags($newPost, $request['tag_list']);
return redirect('posts')->withMessage('Post Saved Successfully !!!');
}
In laracasts tutorial he is just doing a
Article::create($request->all());
I need to do the extra stuff like encrypt, but am i cluttering the method? could it be cleaner?
Do it in the Model. I use the set/get*Attribute() method to change stuff on the fly.
So you could use Article::create($request->all()); then in the model use the fillable array to only autofill what is allowed (such as title, content and published_at).
then use something like (in the model)
function setContentAttribute( $value ){
$this->attributes['content'] = Crypt::encrypt($value);
}
In fact you could also adapt this approach so that the published_at attribute is set to today, or even better use your database to provide now()s time.

Resources