I am a newbie to cakephp3, I am trying to access a "table A" which is not linked to "table B" in the controller of table 2
I want to user category table in UsersController. How to achieve that?
e.g.
user table has three fields id, name, role
category table has 2 fields id, name
articles table has 3 fields id, user_id, category_id, article
In your controller you can use loadModel() to load another table that is not linked to your controller's default model.
class UsersController extends AppController {
public function initialize() {
parent::initialize();
// You don't have to put it in initiliaze
// but if you want to use it in more than one method it's a good place
$this->loadModel('Categories');
$this->loadModel('Articles');
}
public function index() {
// Categories is now available as $this->Categories thanks to loadModel()
$categories = $this->Categories->find()->select(['id', 'name']);
}
}
Related
I'm trying to query multiple tables using Laravel Eloquent Models with one to one, one to many and many to many relationships.
I have a forms table, a brands table a users table and a brand_groups pivot table.
Each form has one brand and one user:
forms
ID
user_id
brand_id
Brands do not have any foreign keys:
brands
ID
Users do not have any foreign keys:
users
ID
And there is a pivot table to create a many to many relationship for creating brand groups that have many users like brand members:
brand_groups
brand_id
user_id
I'm trying to get all the forms that belong to a user either by a direct ownership (forms.user_id) or by brand membership, all the forms from all the brands that the user is a member through brand_groups many to many pivot table.
For example, we have 2 brands, 2 users and 1 user is a member of 1 brand:
brand(ID: 1)
brand(ID: 2)
user(ID: 1)
user(ID: 2)
brand_group(brand_id: 1, user_id: 1)
form(ID: 1, user_id: 1, brand_id: null)
form(ID: 2, user_id: null, brand_id: 1)
form(ID: 3, user_id: 2, brand_id: 1)
form(ID: 4, user_id: 1, brand_id: 2)
Using Laravel Eloquent Models (not direct DB facade calls), I'd like to retrieve all the forms that belong to a user. For the user(ID:1) there are 3 forms:
form(ID:1) direct user ownership
form(ID:2) user is a member of brand(ID:1) group which is the brand of form(ID:2)
form(ID:3) user is a member of brand(ID:1) group which is the brand of form(ID:3)
I gave it a shot using Eloquent: Relationships - Has Many Through:
Has Many Through
The "has-many-through" relationship provides a convenient way to access distant relations via an intermediate relation.
I have tried it like this:
class User extends Model
{
public function forms()
{
return Forms::hasManyThrough(
Form::class,
BrandGroups::class,
'brand_id',
'brand_id',
'id',
'form_id',
)->where('id', $this->id);
}
}
But I get errors like:
BadMethodCallException with message 'Call to undefined method App\Models\Form::brand_groups()'
EDIT
After some digging, I have managed to come up with the working MySQL code that will return all the forms for a user:
SELECT * FROM `forms`
WHERE EXISTS (
SELECT `brand_id`, `user_id`
FROM `brand_groups`
WHERE `forms`.`brand_id` = `brand_groups`.`brand_id`
AND `brand_groups`.`user_id` = 1
) OR `forms`.`user_id` = 1
Now I just need to convert that query to an eloquent model relation.
Eloquent Models
User.php
class User extends Authenticatable implements MustVerifyEmail
{
public function brands()
{
return $this
->belongsToMany(Brand::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
public function forms()
{
return $this->hasMany(Form::class, 'user_id');
}
}
Brand.php
class Brand extends Model
{
protected $table = 'brands';
public function forms()
{
return $this->hasMany(Form::class);
}
public function members()
{
return $this
->belongsToMany(User::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
}
Form.php
class Form extends Model
{
protected $table = 'forms';
public function owner()
{
return $this->belongsTo(User::class);
}
public function brand()
{
return $this->belongsTo(Brand::class);
}
}
UPDATE
I manage to find a query to get all forms related to a user like this:
class User extends Authenticatable implements MustVerifyEmail
{
...
public function allForms()
{
return Form::where(function ($q) {
$q->whereExists(function ($q) {
$q->from('brand_groups')
->where('forms.brand_id', DB::raw('brand_groups.brand_id'))
->where('brand_groups.user_id', $this->id);
})->orWhere('owner_id', $this->id);
});
}
}
How this can be converted to a direct User model eloquent relationship?
Have you tried to Eager Load the User model relationships?
Edit
Firstly: the pivot table name should be the singular -snake_case- name of both tables and should be in alphabetical order (brand_user)
Next, try the following:
return User::where(‘id’, $this->id)->with([‘forms’,‘brands.forms’)->get();
This should return the Forms with direct ownership plus the user Brands and their associated Forms
Here is my problem. I have a table called user and table called skills, also I have a pivot table that connects these two called EmployeeSkill. I am trying to fetch the skills that belong to the user but when i use tinker it returns Base table or view not found: 1146 Table 'pfe_sirh_db.skill_user' doesn't exist (SQL: select skills.*, skill_user.user_id as pivot_user_id, skill_user.skill_id as pivot_skill_id, skill_user.employee_id as pivot_employee_id from skills inner join skill_user on skills.id = skill_user.skill_id where skill_user.user_id = 1)' and am using swagger by the way it returns this "withTimestamps": false
class User extends Authenticatable{
protected $table = "users";
public function skills()
{
return $this->belongsToMany(Skill::class);
}
}
and
class Skill extends Model
{
public function User()
{
return $this->belongsToMany(User::class);
}
}
and the pivot table
class EmployeeSkill extends Model
{
protected $table = "employee_skills";
protected $fillable = [
'employee_id', 'skill_id', 'note'
];
}
Your pivot table should be named skill_user (singular) following the model name they belong to. And you don't need a EmployeeSkill model for this relation to work, you only need the table.
As said in the documentation:
to determine the table name of the relationship's joining table, Eloquent will join the two related model names in alphabetical order. However, you are free to override this convention. You may do so by passing a second argument to the belongsToMany method
And then you should exclude this line:
protected $table = "employee_skills";
change your table name to skill_user
And in your pivot table you should use user_id as a foreign key
You can retrieve all skills from a user by doing this:
$user = User::find(1);
$user->skills();
This will give you all the skills from the user with the id 1
Be aware that you can use any table name and any foreign key name but if you do that you need to specify the names on the relations. So i recommend you doing what i 've told you, since is the standard way
When I try to access articles vie category it works properly here is category.php model
public function articles(){
return $this->belongsToMany('App\Article');
}
but when I try to access category name view article it doesn't work as it's supposed to, I made I mistake there and trying to fix it, but no luck so far. here is the Article model
public function category(){
return $this->hasOne('App\category');
}
and there is a table for relation those two to each others it's called article_category in page where I get all articles for the given tag, I want to do something like $article->category->name there is something sound very wrong to me but I can't figure it out.
The error I'm receiving is
Column not found: 1054 Unknown column 'category.article_id' in 'where clause' (SQL: select * from category where category.article_id = 1 and category.article_id is not null limit 1) (View: C:\wamp64\www\loremipsum\bluhbluhbluh\articleByTag.blade.php)
Btw the way I save the relationship for the article_category when an article is created is
$article->category()->sync($request->category, false);
You've said that article might have only one category. In this case, delete pivot table and add category_id into the articles table.
Then in the Article model define this relationship:
public function category()
{
return $this->belongsTo(Category::class);
}
And in the Category model:
public function articles()
{
return $this->hasMany(Article::class);
}
When you'll do that, you'll be able to access article's category with:
$article->category->name
You have the relationship established incorrectly. Remove the intermediate table and add category_id to the articles table.
Relationships are not set correctly
Category model should be like :
class Category extends Model
{
protected $table='category';
//give me all articles associated with the given category
public function articles()
{
return $this->hasMany('App\Article');
}
}
And Article model
class Article extends Model
{
protected $table='article';
//get the category associated with the given article
public function category()
{
return $this->belongsTo('App\Category');
}
}
for attaching articles to a category:
$article->category()->associate($category)->save();
I am sure this is because of the eloquent, but the query is using the wrong table in SELECT.
here my model:
class Subcategory extends Model
{
public function subcategory()
{
return $this->belongsTo(Category::class);
}
}
and here is my Controller:
class SubcategoriesController extends Controller
{
public function index()
{
$subcategories = Subcategory::all();
return view('pages.subcategories', compact('subcategories'));
}
}
and finally here my error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'developmnet.site.subcategories' doesn't exist (SQL: select * from `subcategories` where `category_slug` = budgets limit 1)
as you can see from the error the table referenced in the query is subcategories when it should be categories table.
My question is how to reference the correct table in this model as I already have one for my main categories and it is working just fine.
To overwrite the table name of a model you can define the protected $table property. In Your case:
class Subcategory extends Model
{
protected $table = 'categories';
// ..
}
If you don't do that, Laravel will derive the table name from the class name. In your case: Subcategory => subcategories.
I have a default authentication table user and another table user_profiles
user(id,email,password)
user_profiles(id,first_name,last_name,mobile)
i am connecting these two table using a many-to-many relationship
for this, i added relationship in the both model class- User and UserProfile
// User Model
public function userProfiles()
{
return $this->belongsToMany('App\Models\UserProfile', 'user_user_profile',
'user_profile_id', 'user_id');
}
//UserProfile Model
public function users()
{
return $this->belongsToMany('App\User', 'user_user_profile',
'user_profile_id', 'user_id');
}
and i tried to access the UserProfle details via user table using
$user=\App\User::find(1)->userProfiles()->get();
but not working and also tried
/$user = \App\User::findOrFail(1)->with('userProfiles')->get();
that is also not working , please help to
Get the user_profile table details along with user table
How to access the Pivot table(user_id,user_profile_id) value
How to display these data from multiple tables into a view form?
You have defined the relationship wrong in your User Model: swap user_id and user_profile_id
// User Model
public function userProfiles()
{
return $this->belongsToMany('App\Models\UserProfile', 'user_user_profile',
'user_id' , 'user_profile_id');
}