Laravel use query in creating event - laravel

what is best and clean way to insert a query value on creating event model like this (Laravel 5.7)
public static function boot() {
parent::boot();
self::creating(function ($model) {
$model->person_job = App\Job::where('person_name',$request->name);
});
}
i don't wanna put this routine query in my controller , so what do professional developers here?

You can use request() function(helper) anywhere in your project if you have no $request variable.
In MVC architecture logic must locate in Controller mostly, Here in Laravel, events mostly are used to do some specific logic(I think that logic mostly does not rely on a user's given data as you do here) on every model based on the event, for example, if you want to generate a unique_id for each Model on created || creating event, or doing caching or something like that.
See here for more about events.

Related

I get all the projects while I only want the projects related to that client

I have two tables, one named Clients and the other named Projects linked together via a foreign key (this is client_id, present in Projects).
In the view related to the list of all clients, I have an additional field that shows me the number of active projects for each client.
So far everything ok! When I click on the number of active projects, I am shown all the projects while I only want those related to that client. So I believe the error is in the condition.
(the withCount below is used to provide me with the number of tasks present in each project)
public function index($id)
{
$projects = Project::withCount(['tasks'=> function (Builder $query) use ($id){
$query->where('client_id', $id);
}])->get();
return view('project.index', compact('projects'));
}
There is certainly an error in the condition written above.
Can anyone kindly help me?
Project::where('client_id', $id)->withCount('tasks')->get();
You were trying to find the client_id inside the tasks
Assuming you have some kind of route that is /client/{client}/projects
You can pass the client into the controller using Route Model binding, and call the projects relationship directly:
public function index(Client $client) {
$client->projects()->get();
}

Laravel: How to use function of relation

I'm facing a situation where a I have to call a function from the controller of a relation instance. For better explanation I will write an example below
I have a Article controller in which I have a preview() function.
A User can have multiple Article.
Let's say that the preview() function parse a text and replace special pieces of text by the user's name.
So my function will looks like this
//In ArticleController
public function preview(Article $article , User $user){
return str_replace("username", $user->name , $article->text);
}
But for a specific situation I want to display a preview of the article when I list all the users
So in UserController
public function index(){
foreach( User::all() as $user){
echo $user->articles[0]->preview( ... );
}
}
Obviously this piece of code will not work.
But I'm more looking of the way to proceed when I face this kind demand.
Should I create a Repository? Use this preview() function somewhere else? Or Is it just a bad practice to do that? What's the best approach or way of thinking when we face this?
Or maybe I'm just missing something important in Laravel's ORM. :/
I assume Article is a model. So you have to add hasMany relation to User (user has many articles). Inside article you have to add preview function. In this case you will be able to find $user->article (or user->articles) and run ->preview function. This is the easiest solution I guess.
You can also add custom attribute like getPreviewAttribute and append it to article model. This way you would have $user->article->preview.

Laravel Eloquent Events Implementation

I am updating my model instance or inserting a new one like this:
$model = Model::updateOrCreate([id' => $request['id']],
$model_to_update_array);
I want to execute some code only when existing model instance ('tourist') was updated (and NOT when a new one was created or nothing changes).
I've read https://laravel.com/docs/5.4/eloquent#events about Eloquent events and it seems to me that I need to use updated or updating event. As I understand these events are 'built-in' in Laravel, so I don't have to use a lot of stuff from here: https://laravel.com/docs/5.4/events
I haven't found a tutorial showing how to implement Eloquent events. Since I am new to events conception at all, it's hard for me to understand how to use them. Can anyone drop a link to a good tutorial about Eloquent events (not events in general, but Eloqeunt events in particular) or maybe it can be shortly explained here?
Thank you in advance!
The easiest way to add Eloquent event for a particular model is to overwrite its boot() method:
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
});
}
When you put this in your model the anonymous function will run every time when the model is being updated. Please note that there is a difference between calling static::updating() and static::updated() depending on when you want to execute your code.
#TheFallen gave a great answer to this problem in another thread on StackOverflow, please read if you are interested in thoroughly explained solution:
Laravel Eloquent Events - implement to save model if Updated

Search object by slug and not by id

I'm a relative beginner with Laravel (using version 5.2.3) and have been working through tutorials on Laracasts and then doing a bit of my own experimenting.
I successfully set up a route that fetches an item from a table by its ID, as shown below
Route::get('/wiseweasel/{id}', 'WiseweaselController#singleArticle');
For simplicity, the controller simply dd's the article
public function singleArticle($id)
{
$article = ww_articles::find($id);
dd($article);
}
This works absolutely fine - I visit eg /wiseweasel/2 and get the contents of the record with id2.
So, I then wanted to use the slug field from the record instead of the id. Since I know the ID method was working, I've tried just modifying this route and controller (also tried creating anew, neither worked) So I now have:
Route::get('/wiseweasel/{slug}', 'WiseweaselController#singleArticle');
and
public function singleArticle($slug)
{
$article = ww_articles::find($slug);
dd($article);
}
The slug for the second record is "secondarticle". So, visiting the url /wiseweasel/secondarticle, I would expect to see the same record as previously dd'd out. Instead, I end up with null.
Even more oddly, using the original id route (/wiseweasel/2) still returns the record... when I have removed all trace of this from the routes and controller, so I would expect this to fail...
This is making me wonder if this could be some odd caching issue? I've tried
php artisan route:clear
in case the route was being cached. I've also tried restarting both Apache and MySql (I'm using XAMMP for both).
Still no luck though... not sure if I've misunderstood how something works or what's going on... so if anyone has any suggestions as to what I might have done wrong, or anything to try, I would be very grateful! :)
You also have the option of using Route Model Binding to take care of this and inject the resolved instance into your methods.
With the new implicit Route Model Binding you can tell the model what key it should use for route binding.
// routes
Route::get('/wiseweasel/{article}', 'WiseweaselController#singleArticle');
// Article model
public function getRouteKeyName()
{
return 'slug';
}
// controller
public function singleArticle(Article $article)
{
dd($article);
}
Laravel Docs - Route Model Binding
Laravel won't automatically know that for slug it should search record in different way.
When you are using:
$article = ww_articles::find($slug);
you are telling Laravel - find record of www_articles by ID. (no matter you call this id $slug).
To achieve what you want change:
$article = ww_articles::find($slug);
into
$article = ww_articles::where('slug', $slug)->first();
This will do the trick (for slug put the name of column in table in database). Of course remember that in this case slug should be unique in all records or you won't be able to get all the slugs.
Maybe it's a bit late for the answer but there is another way to keep using find method and use slug as your table identifier. You have to set the protected $primaryKey property to 'slug' in your model.
class ww_articles extends Model
{
protected $primaryKey = 'slug';
...
}
This will work because find method internally uses the getQualifiedKeyName method from Model class which uses the $primaryKey property.
If you have both routes like this
Route::get('/wiseweasel/{id}', 'WiseweaselController#singleArticle');
Route::get('/wiseweasel/{slug}', 'WiseweaselController#singleArticle');
it will always use the first one. Obviously, there is no id 'secondarticle', so it returns null (although in this case it doesn't matter, they both point to the same method).
The reason is route will search through possible routes till it finds a matching, which is always the one with {id}. Why? You're not telling Route that {id} must match an integer!
You can make sure {id} is understood as an integer, however I suggest using urls like this is a better option
/wiseweasel/{id}/{slug?}
Another suggestion. Do not use names such as xx_articles for a model, but Article instead. This way you can use the new implicit route binding. So using implicit route binding your url would look like this (assuming your model is called Article)
Route::get('/wiseweasel/{article}', 'WiseweaselController#singleArticle');

CodeIgniter 2 and usage of $this->

I'm using CodeIgniter 2 and have installed Ion Auth and also the News tutorial that comes with CodeIgniter.
In the News Controller, the element for the page title is written like this...
$data['title'] = 'Page Title';
However, in the Ion Auth Controller, the element for the page title is written like this...
$this->data['title'] = 'Page Title';
They both seem to work equally well, so can anyone explain the difference(s)? Maybe Ion Auth was written for an older version of CodeIgniter? Is there any practical reason why I'd want to use one over the other? Please link to sources as needed.
I guess it's the author's preference. He likes to use a class property to store the view's data. It allows him to share it across methods. If you look at the author's other projects (Source 1, 2, 3), you can see two examples (source 1 & 2 goes together).
On a side note, for your project, this could allow you to extend the Auth controller with more view data.
class MY_Auth extends Auth {
function __construct()
{
parent::__construct();
}
function index()
{
$this->data['foo'] = 'bar';
parent::index();
}
}
That would allow you to use the $foo variable to your authentication view. (/auth/index in this case.)
In my own projects, I like to use a protected property for my view's data. It does give you much more freedom than a local variable. You don't need to pass the view's data as an argument all the time and you can easily extend your controllers afterward.
Hope this helps!
if you are going to use this $this->data it means you can access $this->data through out the class methods. On the other hand if you are using $data it is only available for the current scope or method and if you need data some where else then you will have to pass it as parameters to the other methods.
Adding $this on the data variable, makes it to be accessible through the class.
I believe the $data or $this->data is only used for "View". It will be passed from the "Controller" to the "View", so we can access that variable through the "View".
So, there will be no differences on the "View" side.

Resources