Is there a way to iterate over all models?
I have a strucure app/Models/{?ModelDir}/{Model}. I just need to check if controller for each model if it uses a trait.
Iterating through the models looks a nice solution for me but I am not sure how to achieve that.
Related
I am looking for a way to add few custom methods which will be used in all models. I can imagine 3 ways of doing it :
Adding custom method to main Eloquent's Model.php class file(I want to avoid doing this as this is a core file)
Creating a custom model class with required custom methods, which will extend to eloquent's Model class and all the models in the project will extend to custom model class.
Adding a trait which will have my methods and include it inside all models
However, I want to do it more efficiently and best way possible. Is their any other way to do it?
PS I am using laravel 5.2 as its an old project.
Based on the comment discussion and adding my experience in Laravel I would suggest you to go either with #2 or #3 approach as #ceejayoz have specified in the comments
first one is definitely a bad approach as you need to modify the core which is not at all a good practice. Second and third are both good approaches.
But, before that you need to check your requirements if literally all models (including any future ones your app will ever have) need the extra functionality, however you can use traits for all models.
If I have the choice probably I will go for traits over custom models as traits are relatively simple then custom models
I'm new at the MVC model. Im still learning on how to use codeigniter framework.
So, i have some questions, is it better to have different controller and different model to perform some functions or is it better to combine all into one controller and one model?
Thanks.
It is all up to you. But consideration seems like having particular controller for one object like User or Article etc. Depending on controller you would like to have appropriate model for manipulating consisting data User_model.php or Article_m.php.
If you have some generic methods and code that you want to pull out from DB from many controllers, you might have something like Generic_m.php.
If you have some other functions related to some area you can make your own library and use those.
For simple functions that don'e belong to any specific set you can create your own helpers.
When working with repository pattern we have interface and some repository classes which implement this interface. If I'm not mistaken, one of the SOLID principles says that those repository classes should return the same type of data for each interface method so that if we switch implementation of the interface nothing breaks down.
If I have an eloquent repository class, which returns an array of eloquent classes of all users, like return User::all(), I have not a simple array but an array of Eloquent models. So instead I might want to use toArray() to return simple array, so that if I switch my implementation of the interface to some other ORM (for example UserDoctrineRepository or I don't know...) everything will still work.
If I understand correctly, inside UserEloquentRepository we use an eloquent model class to help us get data using Eloquent. However, inside my model (User class) I might have some helper methods, like getFullName(). If I simple use toArray() inside UserEloquentRepository I won't get this helper method in my controller, and, eventually in my view.
In other articles I've read they keep it like return User::all(), however, it means that I'm still coupled to Eloquent as I don't get a simple array, but an eloquent objects array
What you get from User::all() or basically every Eloquent query is a Illuminate\Database\Eloquent\Collection. The problem is that when you call toArray() on the collection it will convert all the items of the collection into an array too and you loose all the methods of your model. Instead you can call all() on the collection to get to the array of model objects:
$collection = User::all();
return $collection->all();
Yes that still means you will have Eloquent specific models in your resultset however if you don't use Eloquent features like attribute accessors you will have an easy time replacing it with another type of model.
I'm wondering whether it is possible/advisable to use instances of a laravel model instead of using the Facade. Why all this trouble? I have a model which will be used with many tables, and i want to be setting the model's table automatically using the constructor. Is it possible/advisable, or what is the best approach of achieving the same end?
I have researched around with no much success.
UPDATE
THis is the scenario: an exam system, where different exams are "created". after an exam is created, a table is created in the database under the name Exam_#, where # is the ID of the exam. I want to access all exam from one model: Exam, but you see the particular table the model is to use can vary significantly, so we cannot set the table variable statically. The model shall not know the table it will use until it(the model) is called. So thats why i was wondering whether i can be passing the ID of the exam when i am calling the model or something like that. I hope my question is now more clear.
At the end of this, Laravel is still PHP... Anything you can do in PHP can be done in Laravel.
is (it) possible/advisable to use instances of a laravel model instead of using the Facade?
You can achieve exactly the same results using an instance of the model as you would using the static facade.
$user = User::find(1);
$user2 = new User();
$user2 = $user2->find(1);
Both instances of the above model contain the same results.
Is it advisable? I really don't like the static facades at all, they bring with them more trouble than they are worth, especially when it comes to testing (despite being able to mock them, they create tight coupling where most of us need loose coupling). My answer to this would be: don't use the facades at all.
What is the best approach of achieving the same end?
As #JoelHinz suggested, create a base model with common properties and then use the models as they are intended. i.e. ONE table to ONE model and create the relationships between them. Don't use the same model for multiple tables, this is not how Laravel models were intended and you will lose a lot of the power Eloquent provides by taking the approach you mentioned.
Updates from comments
To get you started with testing in Laravel this is a good end to end tutorial Tutsplus Laravel4 + Backbone. Ignore the backbone part, what you're interested in is the testing parts that start about a 1/3rd of the way down the page. This will get you testing controllers straight away and introduce you to the repository pattern to create testable DAL structures.
Once you get the hang of writing tests, it becomes very easy to write a unit test for anything. It may seem like a scary subject, but that is purely down to not understanding how it works, it really is quite simple. Take a look at the PHPUnit documentation as well, it is an excellent resource.
Im using CodeIgniter 2.0.2 and I noticed while calling a Model from within a Model, you dont need to load it.
For instance, in a Controller you need to write
$this->load->model('my_model');
$this->my_model->my_function();
But in a Model it can load just like this
$this->my_model->my_function();
Should i avoid writing my code like this, or is this safe?
I would avoid writing my code like this, but for a different reason.
Models are generally loaded from controllers, so it seems strange that you would need one model to call another one. Are you sure that there is not a better way to structure your code, such as having a model base class or using a helper for common functionality?