How to mysql query different tables of different controllers in cakephp - php

I have 4 controllers and one database. Each controller is associated with one table. I am not able to query in one controller if i have to access table of another controller. I get "table not found" error.

You need to define the relations between the tables, using the associations:
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
By adding the right colums to your tables (Foreign ID fields) and defining the model associations, you will be able to access all the fields from the related tables.

Your question is a little confusing to say the least. Are you having issues accessing different models inside different controllers or is this an association issue? In your controller, you can define what models your controller uses by setting $uses:
class UsersController extends AppController {
$uses = array('User', 'File');
public function index(){
$results = $this->File->find('all');
}
}

Related

Laravel model relation - change to mutator, without chaning anything in cotrollers

I have 2 tables, estimates and models.
There's a 1-to-1 relation between the two.
I want to move model names from the models table to the estimates table. That will be done with a script that I will have to write myself.
The way this database was set up was wrong, for many reasons I don't need to specify here.
The models table has only 2 columns - id and name.
I access this relation in a lot of controllers, and views all over my app :
$estimate->model_info->name
So I would keep both the models table (with no records) and the Model.php model, keep the old code in the controllers and views, but the new code of accessing model names would be just :
$estimate->name
In the Estimate.php model I have this relation :
public function model_info() {
return $this->hasOne('App\Models\Model', 'id', 'model_id');
}
How can I just change this relation into a mutator, so the old way of accessing model names and the new way would work at the same time?
I've tried the withDefault() callback method with no luck, it returns an empty value :
public function model_info() {
return $this->hasOne('App\Models\Model', 'id', 'model_id')
->withDefault([
'name' => $this->attribute->name
]);
}
Do I have to update my code in all controllers and views or if there's an easier way to do this?

How to Define Relations and Get All Records with Relations in Laravel?

I want to define a relationship between tables, and I don't know where I'm going wrong.
These are my tables:
users
-id
-email
-level
restaurants
-id
-name
-user_id
menus
-id
-name
restaurant_menu
-restaurant_id
-menu_id
-price
In the users table, the field level will set by me with two words: [user] or [restaurant].
User Model
public function restaurant(){
return $this->hasOne(Restaurant::class);
}
Restaurant Model
public function menus(){
return $this->hasMany(Menu::class);
}
Menu Model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
I expect the output of this code:
$result = $restaurant->where('id',2)->menus()->get();
To be records and relations, but i get the following error.
BadMethodCallException
Call to undefined method Illuminate\Database\Eloquent\Builder::menus()
What should I do?
IN user model
public function restaurant(){
return $this->hasMany(Restaurant::class,'user_id','id');
}
Restaurant model
public function menus(){
return $this->hasMany(Menu::class,'id','menu_id');
}
Menu model
public function restaurants(){
return $this->belongsTo(Restaurant::class);
}
As you aspect your output you need to write
$result = Restaurant::with('menus')->where('id',2)->get();
you will get relational data. Like which restaurants has which menus.
You also can use this for your scenario. Use this in your Restaurant model
public function menues(){
return $this>hasManyThrough(Menu::class,restaurant_menu::class,'menu_id','id','id','restaurant_id');
}
Relations you define are not available for you in the query scope of your builder instance the way you tried to call them. They are available in the context of your models. Including your relationships in the queries is done differently - you should check official documentation on the matter first.
In your case, if you want to select all menus that belong to specific restaurant you have to ways:
You can first fetch specific restaurant and then get it's menus via a relationship:
$restaurant = Restaurant::find(2);
$menus = $restaurant->menus;
You can query for menus via Menu model:
$menus = Menu::whereHas('restaurants', function ($query) {
$query->where('id', 2);
})-get();
Also your relations are set up wrong. Based on table structure you've provided your menus and restaurants are in many-to-many relationship. Therefore restaurants() relation method in Menu class needs to return BelongsToMany instance. So while you're at it I would strongly suggest for you to go over relationships documentation and watch examples until you get the concepts of how different relationships work in Laravel.
Actually,
you defined relations in a correct way. I think that, you have an issue about to get those relations on the eloquent queries. If you want to get menu relation of a specific restaurant; you have to implement something like that.
$restaurant = Restaurants::find(2);
$restaurant->menus(); // this will return an array of related menus.
You should read Laravel Offical documentation. There are Retrieving The Relationship headlines for each relationship definition.
There is a problem with your relationship. You have a one to many relationship between restaurant model and menu model. However, your table structure suggests that, they have a many to many model.
If you think your model is right then change the menus table in following way,
menus
-id
-name
-restaurant_id //new field
Also, delete the "restaurant_menu" table.
If you think your database is correct then try changing the model accordingly.

how to implement sub model in Laravel

my base class is post
and many submodel such as : video post , image post
all class have specific attribute & inherit parent attrib
& all class need specific behaviors
Problem
when find on post model elequent give super model(post) instance, its wrong
i need instance of submodel
If I understood you correctly, you need relationships
Add a hasMany relationship to your Post.php model:
public function videos()
return $this->hasMany(App\PostVideo::class);
}
As long as your post_video table has a post_id column that references a post, you can call this relationship like this:
foreach($post->videos as $video) {
// Do something
}
And the inverse relationship:
Add a relationship to your PostVideo.php model:
public function post() {
return $this->belongsTo(App\Post::class);
}
And of course, if you have a video, you can access the post it belongs to by doing:
$video->post
It is looked like you want a single table inheritance. In laravel this could be done manually or use package like nanigans or intrip. To use single table inheritance manually, i could suggest you start with reading this stackoverflow question first. However, notice that single table inheritance put everything in a single table but refered by several models that have different behavior. If this is not what you want, just use simple eloquent queries and models - which already explained by Pistachio.

Laravel - Database, Table and Column Naming Conventions?

I'm using laravel eloquent data objects to access my data, what is the best way to name my tables, columns, foreign/primary keys etc?
I found, there are lots of naming conventions out there. I'm just wondering which one best suits for laravel eloquent models.
I'm thinking of following naming convention:
Singular table names (ex: Post)
Singular column names (ex: userId - user id in the post table)
Camel casing for multiple words in table names (ex: PostComment, PostReview, PostPhoto)
Camel casing for multiple words in column names (ex: firstName, postCategoryId, postPhotoId)
So with this, I could use similar syntax in the controller.
$result = Post::where('postCategoryId', '4')->get();
Are there any recommended Laravel guidelines for this? Can I proceed with these naming conventions?
If someone has better suggestions, I will be very happy to hear them.Thanks a lot!
Laravel has its own naming convention. For example, if your model name is User.php then Laravel expects class 'User' to be inside that file. It also expects users table for User model. However, you can override this convention by defining a table property on your model like,
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $table = 'user';
}
From Laravel official documentation:
Note that we did not tell Eloquent which table to use for our User model.
The lower-case, plural name of the class will be used as the table name
unless another name is explicitly specified. So, in this case, Eloquent
will assume the User model stores records in the users table. You may specify a
custom table by defining a $table property on your model
If you will use user table id in another table as a foreign key then, it should be snake-case like user_id so that it can be used automatically in case of relation. Again, you can override this convention by specifying additional arguments in relationship function. For example,
class User extends Eloquent implements UserInterface, RemindableInterface {
public function post(){
return $this->hasMany('Post', 'userId', 'id');
}
}
class Post extends Eloquent{
public function user(){
return $this->belongsTo('User', 'userId', 'id');
}
}
Docs for Laravel eloquent relationship
For other columns in table, you can name them as you like.
I suggest you to go through documentation once.
I don't agree in general with these examples you both have shown right on here.
It is clean if you take a look at the official Laravel documentation, especially in the Eloquent's relationship session (http://laravel.com/docs/4.2/eloquent#relationships).
Table names should be in plural, i.e. 'users' table for User model.
And column names don't need to be in Camel Case, but Snake Case. See it is already answered: Database/model field-name convention in Laravel?
It is too usual you can see it is like the RedBeanORM: the Snake Case for columns, even if you try other one. And it is adviced to avoid repeating the table names with column ones due to the method you can call from the Model object to access their relationships.
class User extends Eloquent implements UserInterface, RemindableInterface {
public function post(){
return $this->hasMany('Post');
}
}
class Post extends Eloquent{
public function user(){
return $this->belongsTo('User');
}
}
The default table naming conventions can easily cause conflicts with the installation of multiple packages who may have incidentally the same class names. A solution would be to name tables as: [vendor].[package].[class], which is in line with how namespacing in Laravel is applied.
Edited: Using dots in table names is not recommended though. Would there be an alternative convention to use to ensure developers of a modular built application do not need to worry about existing table names.

How should I structure the Eloquent ORM models for multiple intermediate tables in Laravel?

I can't find anywhere the information on how you have several intermediate tables with your Eloquent ORM models. The problem I'm facing is that I have a table for my users, permissions and roles. These are the 4 tables:
Permissions:
id
name
Permission_roles:
id
name
Permission_role_mappings:
id
permission_id
permission_role_id
Permission_role_user_mappings:
id
permission_role_id
user_id
(Well, I also have a users table but the layout of it doesn't matter since the foreign key is in permission_role_user_mapping.)
So the problem is that I want to be able to get the data from the permissions table when calling from the User model. I have some trouble grasping the workflow with Eloquent ORM altogether so if I'm missing something basic which is crucial then please point it out.
According to the documentation it seems that I don't need to create models for the intermediate tables. So how would I specify the relationship from the User class? Could I do something similar to this?
class User extends Eloquent {
public function permission_role()
{
return $this->has_many_and_belongs_to('Permission_Role', 'permission_role_user_mappings');
}
public function permission()
{
return $this->has_many_and_belongs_to('Permission_Role', 'permission_role_user_mappings')->has_many_and_belongs_to('Permission','permission_role_mappings');
}
}
This doesn't seem to be working, this is the error:
User::find(1)->first()->permission()->first();
...
Method [permission] is not defined on the Query class.
I also want to be able to get data by starting from Permission_Role and Permission. I'd prefer that the answer would help me specifying all the models required.
Eloquent relationships are accessed as an object property instead of a function.
User::find(1)->first()->permission;
You can wrap that above statement in the dd function to get a look at it.
This guide on Eloquent Relationships should be helpful
Edit for question in comments about selecting all permissions in the role:
$roles = array();
$permission_roles = User::find(1)->permission_roles()->get();
foreach ($permission_roles as $pr) {
if (! in_array($pr->permissions)) {
$roles[] = $pr->permissions;
}
}
This will get you what you want. However, this will end up doing a lot of queries. It's best to make use of Eager Loading here.

Categories