Eloquent ORM Polymorphic relationship - laravel

I'm trying to build a role-based user management but segmented by resource of many types.
I have this relational model:
I need to show in the user profile management view something like this:
But I don't want to make queries like:
RoleUser::where('user_id',1)->get();
I would like to use the many-to-many polymorphic relationship to take advantage of the Eager/Lazy loading of Laravel, but I don't know to do it.
An other interesting feature to take into account, is that I don't want to store in the database the types like App\Models\Event, App\Models\Article or App\Models\Photo but the map is not working well for me (because the relationships aren't set properly).
//AppServiceProvider::boot()
Relation::morphMap([
'event' => Event::class,
'race' => Race::class,
]);
Any idea?

Try this
//AppServiceProvider::boot()
Relation::morphMap([
'event' => App\Models\Event::class,
'race' => App\Models\Race::class,
]);

Related

Saving data to database in unit testing

Why it's impossible to create dummy data in unit testing like below?
DB::table('users')->insert([
[
'name' => 'test',
],
I saw that in order to create data you need to create factory, but when I try to insert data like this:
User::factory()->count(1)->create([
'name' => 'test'
]);
It also don't insert new data.
What is the easiest way to to that? Thank you
No need for a factory, and you dont need to use DB if you a User model setup. Laravel is great for these types of things and I recommend reading the docs here
For you problem its as simple as this
User::create(['name' => 'test']);

CakePHP 3 sessions table in database

I have some questions regarding having CakePHP 3 sessions table stored in the database:
1) Is there a way to remname the table from sessions to a different name? If yes, where should I specify the new name?
2) Similarly to question 1: Is there a way to remname the names of colums in sessions table, so that CakePHP would still operate correctly?
3) Is there a simple way to add even the most basic encription of the data column of sessions table?
So I will cite the database session docs and then also provide some answers. The answers in the docs are more complete.
Specify the model you want to use by including a 'model' key.
'Session' => [
'defaults' => 'database',
'handler' => [
'engine' => 'DatabaseSession',
'model' => 'MyCustomSessions'
]
]
The DatabaseSession handler appears to hard code 'data' and some of the other columns. However, you can (and should) extend that class if you want to do something special
Based on what you want to do it appears creating your own SessionHandler is the way to go. It is quite simple to do and it is outlined in the docs.
My best advice would to take a peek at cake's DatabaseSession. It seems that your requirements are special and it is probably your best course of action.

Laravel change stored value of polymorphic relationship

I am trying to make the stored value of a polymorphic relationship more readable by other applications. Currently the polymorphic model type is stored as the FQCN of the model. Using the example in the Laravel Docs, imageable_type could be "App\Product", or "App\Staff". However, this value can be a little more difficult to manage if any non-laravel applications which aren't based on this convention and are also accessing the same database. Also, if the model FQCN ever gets refactored, you have to modify your other applications to account for the change.
Is there a way to change the type to something more consistent and readable, and then have a mapping class that maps the keys to the model? (e.g. have "product" map to "App\Product")
Yes. This is a change that was recently implemented.
Add this to your service provider (in the boot method):
Illuminate\Database\Eloquent\Relations\Relation::morphMap([
'product' => App\Product::class
]);
If you simply pass an array of model names, it'll default to using the table names:
Illuminate\Database\Eloquent\Relations\Relation::morphMap([
App\Product::class,
App\Staff::class,
]);
if you are adding morphMap method to service provider, you might want to use
'product' => \App\Product::class
( "\" before App),otherwise your namespace can be wrong.

Where clauses: Grocery CRUD and CodeIgniter

I have two tables that need to be linked: 'user' and 'dealer'. The relation table is 'user_dealer'.
I found using $crud->set_relation_n_n() works well for edit and add screens to restrict which records are edited and added, like this:
$crud->set_relation_n_n('Dealers', 'user_dealer', 'dealer', 'user_id', 'dealer_id', 'dealer', null, array('id' => $this->session->userdata('dealer_id')));
But for some reason, this does not work for the LIST grid.
I tried $crud->where() but this does not work, as it does not have the column from the relation table there.
Can anybody help, please?
Apparently this is not possible, so I had to write a custom model that extends the Grocery Crud model and do what I needed to do.

Relations function in AR Model, many to one relationship

So here's the scenario:
I have two table, Issue & Project.
A Project can have many Issue and an Issue can exactly one project.
Since Issue is many to one, do you have to define it?
Cause I know in Project Model I have:
public function relations()
{
return array(
'issues' => array(self::HAS_MANY, 'Issue', 'project_id'),
'users' => array(self::MANY_MANY, 'User', 'tbl_project_user_assignment(project_id, user_id)'),
);
}
For Issue Model I have nothing but foreign keys:
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'requester' => array(self::BELONGS_TO, 'User', 'requester_id'),
'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),
'project' => array(self::BELONGS_TO, 'Project', 'project_id'),
);
}
I'm guessing anything to one relationship does not need to be define?
Thank you in advance.
BTW, I'm doing agile Yii book and I ended up asking myself this question.
There's a has-one option in AR class (http://www.yiiframework.com/doc/guide/database.arr).
But is this case optional for some reason?
It helps me to think of the difference between BELONGS_TO and HAS_ONE as "where is the foreign key stored"? If the Project model stored "Issue_Id" then potentially Issue could have many Projects. You use the HAS_ONE relationship to state that even if Issue COULD have many projects, it only has ONE.
However, the more common case is if you are storing the Project_Id in the Issue model (and I assume you are). Then you have to use the BELONGS_TO relationship. It appears you have defined the relationships correctly above.
Someone posted a similar question relating to Yii relations here that I helped answer:
yii - using relation HAS_ONE to get data from the related table to display in list page
As to your concern about "needing" to define relationships, you don't "need" to define any. You could write your own SQL queries to do the same thing. The ActiveRecord relations are just a convenience thing to make querying for related records simpler. If you are never going to look up an Issue's Project, then you don't "need" to define the "project" BELONGS_TO relationship.
Without actually seeing your database structure it looks to me like you have everything set up correctly. You can now easily make both $issue->project and $project->issues "lazy" relational queries, taking full advantage of the power of the Relational Active Record. Cheers and good luck with project!
In your Issue model you already have the relation specified as BELONGS_TO the project model.
I also just got the new yii-book. It helped me alot!
Happy coding :)

Resources