I have following two tables:
account:
+--------------------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+---------------------+------+-----+---------+-------+
| id | varchar(25) | NO | PRI | | |
| name | varchar(191) | NO | UNI | NULL | |
| status | tinyint(3) unsigned | NO | | NULL | |
| active | tinyint(3) unsigned | NO | | NULL | |
project:
+-----------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| client_code | varchar(191) | NO | | NULL | |
| tags | varchar(500) | YES | | NULL | |
| project_id | int(11) | NO | | NULL | |
| file_name | varchar(191) | NO | | NULL | |
| total_records | int(11) | NO | | NULL | |
There's a one-to-many relationship between account and projects.
Foreign key in projects table is named account_code instead of account_id.
The issue being project identifier column that is of significance is project_id rather than id in projects table.
Here's my Account model:
public function projects() {
return $this->hasMany('App\Project', 'account_code');
}
Project model:
public function account() {
return $this->belongsTo('App\Account', 'account_code', 'project_id');
}
I have a row in projects table as:
id: 9
account_code: 0011T00002K95MLQAZ
tags: cpi|test|dmf
project_id: 312
file_name: conf_matrix_dev_1579064650.tsv
total_records: 19
I tried retrieving account detail that project_id 312 belongs to.
$project = \App\Project::where('project_id', 312)->get();
dd($project->account->name);
This throws exception:
Property [account] does not exist on this collection instance
and with this:
$project = \App\Project::find(312);
this tried to look into by id field instead of project_id.
How can I solve this without having to write a query?
The problem here is that get is retrieving you a collection instead of an instance. You can use
$project = \App\Project::where('project_id', 312)->first();
instead and that should do the trick.
Hope it helps. Some other solutions are exposed here: Property [title] does not exist on this collection instance
Related
I have two tables schools and subscriptions. I already get the school_id from my subscriptions table. My problem is when I want to get the description column from schools table. I get an error Call to undefined relationship [description] on model [App\Subscription]. Can someone tell me what is the problem of my codes? I already defined the relationship in my models and in the migration. I don't want to use querybuilder because its too confusing. Thanks.
Schools Model
class School extends Model
{
protected $fillable = ['description'];
public function user(){
return $this->hasMany('App\User');
}
public function subscriber()
{
return $this->belongsTo('App\Subscription','description');
}
}
Subscription Model
class Subscription extends Model
{
protected $fillable = [
'id', 'school_id', 'start_date', 'end_date',
];
public function subscriptions(){
return $this->hasMany('App\School','description');
}
public function plans(){
return $this->belongsTo('App\Plan');
}
}
My controller
$subs = Subscription::findOrFail($id)->with('description')
->get();
$plans = Plan::get();
dd($subs);
PS. When i only put$subs = Subscription::findOrFail($id); I get this data in dd
#attributes: array:8 [▼
"id" => 2
"school_id" => 2
"start_date" => "2019-09-27"
"end_date" => "2019-10-27"
"created_at" => "2019-10-17 03:36:13"
"updated_at" => "2019-10-17 03:36:13"
"plan_id" => 2
"status" => 1
]
Schools Table
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(191) | NO | UNI | NULL | |
| description | text | NO | | NULL | |
| logo | varchar(191) | YES | | NULL | |
| main_server | varchar(191) | YES | | NULL | |
| local_server | varchar(191) | YES | | NULL | |
| status | int(11) | NO | | 1 | |
| updated_by | varchar(191) | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
Subscriptions
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| school_id | int(10) unsigned | NO | MUL | NULL | |
| start_date | date | YES | | NULL | |
| end_date | date | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| plan_id | int(10) unsigned | NO | MUL | NULL | |
| status | int(11) | NO | | NULL | |
+------------+------------------+------+-----+---------+----------------+
EDIT: I just want to get the description from school_id that i get from $subs
In Subscription Model change the relation function subscriptions
public function subscriptions(){
return $this->hasMany('App\School', 'id', 'school_id');
}
call the eloquent query to
$subs = Subscription::with('subscriptions')->findOrFail($id);
dd($subs->subscriptions[0]->description);
You call wrong relation. You have defined subscriptions and not description relation in your Subscription Model.
Maybe it's typo?
you can change your relationship to :
public function description(){
return $this->hasMany('App\School','id', 'school_id');
}
and then just call it like:
$subs = Subscription::with('description')->findOrFail($id);
I'm working in Laravel and need help with database relations. I have three tables:
projects:
+------------+--------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(191) | NO | | NULL | |
| url | varchar(191) | YES | | NULL | |
| updated | bigint(20) unsigned | YES | | NULL | |
| type | enum('adobe','invision','pdf') | NO | | NULL | |
| preview_id | int(10) unsigned | YES | MUL | NULL | |
+------------+--------------------------------+------+-----+---------+----------------+
users:
+----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(150) | NO | UNI | NULL | |
| password | varchar(179) | NO | UNI | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
+----------------+------------------+------+-----+---------+----------------+
projects_users
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| project_id | int(10) unsigned | YES | MUL | NULL | |
| user_id | int(10) unsigned | NO | MUL | NULL | |
+------------+------------------+------+-----+---------+----------------+
Situation: There are several projects, and multiple users can work on multiple projects (ManyToMany).
I need to select (SELECT-statement) all users working on project with e.g ID 1.
How would I do that in plain SQL, and how would I do that in Laravel code (without a raw-sql-query function).
I already looked here but I ain't really catching it.
Thanks!
Use the whereHas() method:
$users = User::whereHas('projects', function($q) use($projectId) {
$q->where('id', $projectId);
})->get();
class Project extends Model{
public function users()
{
return $this->belongsToMany('App\User', 'projects_users');
}
}
class User extends Model{
public function projects()
{
return $this->belongsToMany('App\Project', 'projects_users');
}
}
$project = Project::find(1);
$project->users //list of all the users
I am using Entrust's default table structure:
permissions table:
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| display_name | varchar(255) | YES | | NULL | |
| description | varchar(255) | YES | | NULL | |
| created_at | timestamp | NO | | NULL | |
| updated_at | timestamp | NO | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
permission_role table:
+---------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+-------+
| permission_id | int(10) unsigned | NO | PRI | NULL | |
| role_id | int(10) unsigned | NO | PRI | NULL | |
+---------------+------------------+------+-----+---------+-------+
roles table:
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| display_name | varchar(255) | YES | | NULL | |
| description | varchar(255) | YES | | NULL | |
| created_at | timestamp | NO | | NULL | |
| updated_at | timestamp | NO | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
Now, given a role_id I'd like to get select the following from this database:
permissions.id
permissions.display_name
whether the permission_role table contains an entry with the permission_id and the given role_id
The last one turned out to be a bit tricky in Eloquent.
This SQL query accomplishes exactly what I need (ID is obviously replaced by a valid role ID):
SELECT p.id, p.display_name, IF(pr.role_id = ID, 1, 0) AS has_role
FROM permissions p
LEFT OUTER JOIN permission_role pr ON p.id = pr.permission_id;
Example output:
+----+--------------+----------+
| id | display_name | has_role |
+----+--------------+----------+
| 1 | Edit users | 1 |
| 2 | View users | 0 |
| 3 | Delete users | 0 |
+----+--------------+----------+
Can anyone help me out here, on how to do this using Eloquent?
I've tried this, but it always returns 1 (true) in the third column, unlike the SQL query (as seen above).
$result = DB::table('permissions')
->leftJoin('permission_role', 'permission_role.permission_id', '=', 'permission_role.role_id')
->select(DB::raw('permissions.id, permissions.display_name, IF(permission_role.role_id = ID, 1, 0) AS has_role'))
->get();
Ideally, I'd like to do this without using DB::raw, although it is completely fine if that is what it takes.
Thanks in advance for any help!
Structurally, the Query Builder query you've shown looks fine.
What does not look fine is the left join. Shouldn't this:
->leftJoin('permission_role', 'permission_role.permission_id', '=', 'permission_role.role_id')
be this:
->leftJoin('permission_role', 'permission_role.permission_id', '=', 'permissions.id')
?
I'm using Laravel 4. I have many to many relationships in my system. And I choose to use Wordpress taxonomy table scheme.
But how can I make models relationships with Laravel 4 Eloquent ORM? Here is my database tables;
Table terms:
+------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------+------+-----+---------+----------------+
| term_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(200) | NO | MUL | | |
| slug | varchar(200) | NO | UNI | | |
+------------+---------------------+------+-----+---------+----------------+
Table term_taxonomy:
+------------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+---------+----------------+
| term_taxonomy_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| term_id | bigint(20) unsigned | NO | MUL | 0 | |
| taxonomy | varchar(32) | NO | MUL | | |
| description | longtext | NO | | NULL | |
| parent | bigint(20) unsigned | NO | | 0 | |
| count | bigint(20) | NO | | 0 | |
+------------------+---------------------+------+-----+---------+----------------+
Table term_relationships:
+------------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+---------+-------+
| object_id | bigint(20) unsigned | NO | PRI | 0 | |
| term_taxonomy_id | bigint(20) unsigned | NO | PRI | 0 | |
| term_order | int(11) | NO | | 0 | |
+------------------+---------------------+------+-----+---------+-------+
Normally we can do return $this->belongsToMany('Term'); but how can we do 2 relationships? We need 2 relationships first find term taxonomy from "term_taxonomy" table, after find term relations with "taxonomy_id".
And an example for how I want to use;
$categories = Post::find(1)->categories; // get terms with taxonomy="post_category"
$tags = Post::find(1)->tags; // get terms with taxonomy="post_tag"
I don't want to do this with basic database class "DB::table('table')->join('...')..." I want to use Eloquent relation methods and models.
You can create getter methods to handle these:
In your Post model, create new methods something along the lines of:
public function getCategories()
{
return $this->hasMany()->where('taxonomy', 'post_category');
}
public function getTags()
{
return $this->hasMany()->where('taxonomy', 'post_tag');
}
It's CakePHP-2.0 and CakeDC-Users plugin
mysql> describe comments;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| post_id | int(11) | NO | MUL | NULL | |
| user_id | int(11) | NO | | NULL | |
| body | varchar(500) | NO | | NULL | |
| mark | tinyint(4) | NO | | 1 | |
| created | datetime | YES | | NULL | |
| modified | datetime | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
I need the username not the user_id. How can i set the association between Users.User model and Comment model and with Post model.
So far i have this in Comment model public $belongsTo = array('Post','Users.User');
Can anyone please explain with example about this association?
the field user_id is a foreign key in that table.
Cake will automatically fetch records related to that id, including username and other fields depending on your recursive level.