Laravel 5.2 Eloquent Relationships with Irregular Names - sql

I'm building out my first project in Laravel and have run into a bit of a snag with a one to many relationship between two tables.
Historically, I would have done something like this in SQL to achieve my end goal:
SELECT tag_key.key
FROM tag
LEFT JOIN tag_key
ON tag.tag_key_id = tag_key.id;
With Laravel, I'm trying to do things the ORM way and am getting hung up, probably on a naming thing somewhere down the pipe. Here's the code:
Part 1: Migrations:
"tag_keys" table
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagKeysTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tag_keys', function (Blueprint $table) {
$table->increments('id');
$table->string('key', 128);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tag_keys');
}
}
"tags" table
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('value', 128);
$table->integer('tag_key_id')->unsigned()->index();
$table->foreign('tag_key_id')->references('id')->on('tag_keys')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tags');
}
}
Part 2: Models:
"TagKey" model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class TagKey extends Model
{
protected $fillable = [
'key'
];
protected $dates = [];
protected $table = 'tag_keys';
/**
* Tag Keys have many Tags
*/
public function values()
{
return $this->hasMany('App\Tag');
}
}
"Tag" model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
protected $fillable = [
'value',
'tag_key_id'
];
protected $dates = [];
/**
* Tag values belong to Tag Keys
*/
public function key()
{
return $this->belongsTo('App\TagKey');
}
}
Independently, they both work just fine. However, when I jump into tinker and try this (given there is a valid row in both the "tag" and "tag_key" tables and given that id 1 in the "tag" has the value of 1 in the "tag_key" table under the "tag_key_id" column):
$tag = App\Tag::first();
$tag->key;
=> null
What am I missing here? How do I build this association?

When the foreign key name doesn't follow Eloquent conventions ("snake case" name of the owning model and suffix it with _id), you should specify it in the relationship:
TagKey object:
return $this->hasMany('App\Tag', 'tag_key_id');
Key object:
return $this->belongsTo('App\TagKey', 'tag_key_id');
More info in the documentation

Related

in laravel hasMany() relation is working but belongsTO not working

i have two tables 1: users 2: roles
as for migration of users table like this
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('role_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('username');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('profile_image')->default('user.png');
$table->text('about')->nullable();;
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
`
as for roles table migration
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('role_title');
$table->string('role_slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
};
`
User mode
`
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Models\Role;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public function role(){
return $this->belongsTo(Role::class);
}
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
`
Role model
`
<?php
namespace App\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Role extends Model
{
use HasFactory;
public function users(){
return $this->hasMany(User::class);
}
}
`
so i have tried
App\Models\Role::find(1)->users;
so it is returning
`
Illuminate\Database\Eloquent\Collection {#4831
all: [
App\Models\User {#4829
id: 2,
role_id: 1,
name: "zahid",
username: "admin",
email: "admin#gmail.com",
email_verified_at: null,
#password: "$2y$10$6Up.B4.0gytPsVWOT/f0eeG4yk.u466FDRNf34yYZwxbwyKJh8o8u",
updated_at: null,
},
],
}
`
and
App\Models\User::find(2)->roles;
it is returning null
please tell me where is my fault in code why my belogsTo not working. i want for one use lke jone or nike contains only one role lke author or admin or writer etc. but one role lke admin or it could be contain multiple users lke multiple user can be admin or author.
is in my logic any fault or in code above.
plz help me. and thank for advaced for all helpfull code loves.

Laravel SQLSTATE[42000]: Syntax error or access violation: 1064

Hi i want to create a foreign key but nothing work and i don't understand whyenter image description here
enter image description here
Please provide more info about table type, for now based on info that you type I can suggest you check are you using InnoDB tables? does FOREIGN KEY in table one corresponding to PK in table 2? are they have same types and length?
articles table
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArticlesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title' , 255);
$table->text('content');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('articles');
}
}
category table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoryTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('category', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('category');
}
}

Error adding a foreign key in Laravel 5.2 through migrations

I have two migrations as shown below:
2016_02_03_071404_create_company_users_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCompanyUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('company_users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies');
$table->char('role', 20);
$table->text('first_name');
$table->text('last_name');
$table->integer('age');
$table->string('email')->unique();
$table->text('password');
$table->text('login_type');
$table->string('phone_number')->unique();
$table->integer('verified')->default(0);
$table->text('profile_picture');
$table->text('facebook_id');
$table->text('twitter_id');
$table->text('linkedIn_id');
$table->text('google_plus_id');
$table->text('current_location');
$table->text('established_year');
$table->text('device_type');
$table->text('device_token');
$table->text('device_model');
$table->text('device_os_version');
$table->text('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropifExists('company_users');
}
}
2016_01_28_144808_create_jobs_table.php
<?php
use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateJobsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('job_title');
$table->text('job_description');
$table->text('job_industry');
$table->text('job_location');
$table->integer('job_experience');
$table->text('employment_type');
$table->bigInteger('recruiter_id')->unsigned();
$table->foreign('recruiter_id')->references('id')->on('company_users');
$table->tinyInteger('status')->default(1);
$table->timestamp('posted_date')->default(Carbon::now()->toDateTimeString());
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropifExists('jobs');
}
}
When I run php artisan migrate I get the following error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table jobs add constraint jobs_recruiter_id_foreign foreign
key (recruiter_id) references company_users (id))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
Please help.
I figured it out... it was basically the order of execution of the migration files. So i changed the timestamps of the migration files to reorder the execution.... Works like charm.

Please explain the foreign_key and local_key in Laravel ORM relationships

I'm effectively trying to define the relationships between users (sender and recipient) and messages.
My Messages migration is:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMessagesTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
//
Schema::create('messages', function($t){
$t->increments('id');
$t->integer('sender_user_id')->unsigned();
$t->integer('recipient_user_id')->unsigned();
$t->string('subject');
$t->text('content');
$t->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
Schema::dropIfExists('messages');
}
}
My Message model was straightforward:
<?php
class Message extends Eloquent{
// link to sender user id
public function from(){
return $this->hasOne('User', 'sender_user_id');
}
// link to recipient user id
public function to(){
return $this->hasOne('User', 'recipient_user_id');
}
}
But I'm unsure in defining the hasMany relationships in my User model.
The docs (http://laravel.com/docs/eloquent#relationships) shows the following:
return $this->hasMany('Comment', 'foreign_key');
return $this->hasMany('Comment', 'foreign_key', 'local_key');
Now, I'm confused which key is which in the latter hasMany relationship. Which is correct for my User model?
public function sentMessages(){
return $this->hasMany('Messages', 'id', 'sender_user_id');
}
public function sentMessages(){
return $this->hasMany('Messages', 'sender_user_id', 'id');
}
You have to set your relation like this:
public function sentMessages()
{
return $this->hasMany('Messages', 'sender_user_id');
}
public function receivedMessages()
{
return $this->hasMany('Messages', 'recipient_user_id');
}

How to create a laravel model that implements an API?

When I create a Model, it initially looks something like this:
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
....
.. etc
The problem is, it connect to a DB. I want a way that it skips the fact that I want it to connect to a DB, but rather allow me to overwrite the functions like this:
function find($id) {
//insert curl api call to get user id
}
How does one do that?
You can just override them all:
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $table = 'users';
public static function find($id, $columns = array('*')) {
//insert curl api call to get user id
return $model;
}
}