I am trying to unit test creating a company however I don't know what the fields/attributes of the model are.
So I look in App\Company.php, but there is no list of fields there.
Then I look at the migrations, but I have to go through each of them to find the fields available.
So as a last resort I open a DB explorer to find what fields are in the model.
Is there an easier way to know what fields exist in a model?
You can do it this way, without the need of loading any object from the db:
$fields = (new \App\Company())
->getConnection()
->getSchemaBuilder()
->getColumnListing((new \App\Company())->getTable());
Also you can:
$fields = Schema::getColumnListing((new \App\Company())->getTable()));
The easiest way is to use the getAttributes() method on an existing object.
This will give you all database columns of that object.
I would search for the migration of the database table (in database/migrations/). If there isnt any migration I would go for the anwser #Luceos gave.
Related
**USER MODEL**
public function post(){
return $this->hasOne('App\Post','user_id','id');
}
**WEB ROUTE**
use App\User;
Route::get('/{id}/post',function($id){
return User::find($id)->post;
});
Hi everyone, I'm fairly new to both PHP and Laravel and have been struggling a bit. I just have 2 questions for this code.
In the web routes, why doesn't post have any () beside it? It was declared a function in the user model. And.. I am unsure of how these relationships work (correct me if I am wrong) but does the code above look for a user with a specific $id and connects it with a post having a similar $user_id value?
For the first bit, it is a dynamic property, here you can find how you can actually make one yourself Laravel: create a dynamic property. They essentially work because the result is a single object search based on the id, since it doesn't have to retrieve a collection it allows itself to be accessed like an attribute of the object.
And yea pretty much on the second one. It also uses laravels models to retrieve the data from the database so that you get an object back without needing to create the repositories yourself.
There are major differences between User::find($id)->post and User::find($id)->post(). First one is returning the result of the related relations so you get the post that has user_id equal to $id.
The second one returns a query builder,so you can add more conditions. For example User::find($id)->post()->where("status", 1)->get().
My question is if it is possible to add all the fields directly to a new model via Eloquent.
I guess it would be something like
php artisan make:model MyModel --fields=?
However, I can't find anything related with that. Anyway, I have to generate a lot of model and any trick would be really appreciated.
Thanks in advance
If you mean table's column by fields then:
Firstly you don't need to define fields in modal. I mean in Laravel no need to define fields while creating model. Besides, model automatically work with your database table's columns as its property.
So, now you may want to define columns while creating migration, not while creating model. There is library to serve this demand named as Generator(https://github.com/laracasts/Laravel-5-Generators-Extended) maintained by Laracasts.
Using this generator you can generate migration file to create table in DB specifying their column names and their type also. Here is a example from their Github repo, how you can do this:
php artisan make:migration:schema create_users_table --schema="username:string, email:string:unique"
You can checkout their documentation for more information. Best of luck.
It's not possible with make:model or make:migrations commands, but you can create your own console command and add this feature by yourself.
Also, take a look at source code of make:model and make:migration commands to get some ideas on how to do that.
it looks like only built in options are --migration and -m to include a migration with the model generation. L5.3 Docs
There does look like there is a package for L5.0, which looks like it would work in 5.*+. It is put out by Laracasts:
https://github.com/laracasts/Laravel-5-Generators-Extended
It also looks like you can make a custom solution as well:
https://laracasts.com/discuss/channels/tips/l5-artisan-command-makemodel
Hope that helps!
No options while creating a model,
This is my terminal output (laravel 5.3) while i check,
You don't need to mention fields while creating model.
Ex:- based on the rules you should keep the names as like below,
model name as User
table name as users
then the model automatically handle everything, you don't need to mention the table/fields name.
I was looking for the same thing myself, as I used to work like that in previous frameworks, but could not find it, or at least not as I wanted it, so I did my thing. You can check it out if you like:
https://github.com/Triun/laravel-model-base
It will read your database, and create the laravel eloquent models for you.
It is meant to be very flexible, so the configuration may be a little complex, and I guess that I didnt' catch up with the documentation, but you can ask me if you don't know how to make it do what you want.
Basically it has 4 customization levels:
By out of the box modificators, configurable by the config files.
Including interfaces and traits to your auto-generated models.
Create your own modificators. Classes where you receive the model skeleton before it is saved, so you can add or remove properties, methods, etc.
Generate the model base, but edit yourself the final model.
And, of course, suggestions and contributions are more than welcome.
I've read a lot of documentation about how to handle models and forms in yii and I've found a solution that works for the case that I explain following, but the problem is that the code is complex to write and to maintain, so I'm looking for suggestions.
The case is the following: I need to save together two different models and a third model that is a tabular input (more instances of the same model).
For instance, I may want to save a Blog post (first model) with the author information (second model) and a list of references (third model, the tabular one).
I'd like to validate all of them via ajax in one step and save them transactionally.
I've read all of these link.
http://www.yiiframework.com/wiki/559/tabular-input-validating-and-saving-related-models/
multi model forms in yii
http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models/
http://www.yiiframework.com/wiki/218/how-to-use-single-form-to-collect-data-for-two-or-more-models-cactiveform-and-ajax-validation-edition/
http://www.yiiframework.com/doc/guide/1.1/en/form.table
http://www.yiiframework.com/wiki/362/how-to-use-multiple-instances-of-the-same-model-in-the-same-form/
http://www.yiiframework.com/forum/index.php/topic/14082-transaction-on-multiple-ar/
http://www.yiiframework.com/wiki/559/tabular-input-validating-and-saving-related-models/
https://github.com/yiiext/with-related-behavior
The last link is interesting, but if someone has one best practice to share, I'll be thankful to him.
I think you are looking for something like this: http://www.yiiframework.com/extension/eadvancedarbehavior/
This is an extension that does exactly that you asking.
Quoted from the link:
HAS_ONE and HAS_MANY
Suppose a User HAS_ONE Address and HAS_MANY Emails, and Address/Email BELONGS_TO User (both have the foreignkey column user_id).
So you can do now:
$blog = new Blog();
$blog->author = $author; //the author model object
$blog->references = array( $references1, $references2, ... ) ; //reference model objects
$blog->save();
I think you understand how to setup the forms? Those links you send are pretty clear about it.
TL;DR - How do I massively assign private fields in Yii?
Any Yii experts on StackOverflow? The YiiFramework forums didn't really help me out.
I've got a private field hired in my CActiveRecord model that is dependent on another relation jobCount. Basically, if there is at least one valid job (stored in another table) associated with that member, they are consider hired.
Conventionally, I would set hired in the afterFind method, but that would mean loading the relation every time. For the sake of saving database queries, I would only like to load the relation if hired is needed. So I set hired to private, and can load the relation and set it once getHired() is called.
So far so good...
The problem arises once I incorporate the hired field in my CGridView. I'd like to be able to use the column filters, with a simple dropdown filtering on Yes or No. Upon filling out your filters, CGridView passes back a GET request, which you would set to a cleared model using massive assignment...
$model->attributes = $_GET['ModelName'];
Obviously I would like hired to get set as well, despite it being a private field. (I handle the searching for CGridView, don't worry about that.) I've made it a safe field in my model, but it doesn't get set.
setHired() function doesn't get called
setAttribute() function doesn't get called
setAttributes() function doesn't get called
What's the correct way to do this? Clearly, I could just add an extra line in my controller action...
if (isset($_GET['ModelName']['hired']))
$model->setHired($_GET['ModelName']['hired']);
...but I would really rather learn how to allow private fields to be massively assigned.
I realize that this is rather convoluted. If you see some way that I could streamline this hired bit, I'd appreciate that. Still, I would like to learn if there's a way to do this.
I suppose, you need just to add your attribute to the list of attributes.
public function attributeNames()
{
$names = parent::attributeNames();
$names[] = 'hired';
return $names;
}
I want to save all but some excluded fields. I know that I can do it this way
$this->Blah->save($this->data,false,$fieldList)
Where $fieldList contains all the data fields of the table but these I don't want to get saved. I have some tables that have maaany data fields, and I don't want to write the whole list from scratch in every single controller action (yes, the fields that should not be saved differ from action to action). Additionally, it looky messy and confusing. Is cakePHP providing something ready-to-use for this case? If not, I guess, I'd have to implement it by myself by adding a $fieldList property to every controller and doing something like this (ugly-hacked-together-solution):
$tmp = $fieldList;
unset(array_search('fieldtoexclude', $tmp));
$this->Blah->save($this->data,false,$tmp);
Best Regards
function blacklist($blackList = array()) {
return array_diff(array_keys($this->schema()), $blackList);
}
shoud work
Take a look at:
http://www.dereuromark.de/2010/09/21/saving-model-data-and-security/
for details
If the field list changes from action to action, then you're looking for an automagic function that can read your mind. Cake doesn't provide that!
Somewhere you have to say which fields are to be excluded and doing so longhand in a clear way will make your code much more maintainable.
If it is only one controller, define the list as a class variable, or alternatively subclass the save action on the model.