Laravel relationships seems to not working - php

I have an Item and AdvertItem objects in Laravel. I want to create a 1 to 1 relationship between an item and advert item
The item class looks like this
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
//
public function Category(){
return $this->belongsTo(Category::class);
}
public function Currency(){
return $this->hasOne(Currency::class);
}
public function AdvertItem(){
return $this->hasOne(AdvertItems::class);
}
}
and the AdvertItem class looks like this
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AdvertItems extends Model
{
protected $guarded = [];
//
public function items(){
return $this->belongsTo(Item::class);
}
}
but when I call advertItem I only see item_id = 1 instead of item object.
Item table is created like this
class CreateItemsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('description');
$table->unsignedBigInteger('currency_lookup_id');
$table->unsignedBigInteger('category_id')->index();
$table->unsignedBigInteger('price');
$table->string("image_path");
$table->string('sale_ind');
$table->Date('eff_from');
$table->Date('eff_to');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('item');
}
}
And advert table is created like this
class CreateAdvertItemsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('advert_items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('item_id');
$table->unsignedBigInteger('customer_id');
$table->Date('eff_from');
$table->Date('eff_to');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('advert_items');
}
}
please assist.

The following rules will assist you.
Always start relationship names with lower case. Save capitals for Classes not methods.
Models should be Singular
Pay attention to the plurality of names. Things that there should only be one of should be singular. So, in your 1:1 relationships, both relationship names should be singular.
AdvertItem class
public function item(){
return $this->belongsTo(Item::class);
}
then, if you have Item and want AdvertItem, you should load it
$item->load('advertitem');
or the other way around
$advertItem->load('item');

Related

How to create Models & Migrations & define relationships by running one command

I want to run a custom command like
php artisan make:custom-model MODEL_NAME_1 MODEL_NAME_2 --type=RELATION_TYPE
which creates two Models and two Migrations with the defined relationship.
For example, if I run this:
php artisan make:custom-model Author Book --type=nn
So the newly created Models go here:
class Author extends Model
{
use HasFactory;
public function books()
{
return $this->belongsToMany(Book::class);
}
}
class Book extends Model
{
use HasFactory;
public function authors()
{
return $this->belongsToMany(Author::class);
}
}
With these Migrations:
class CreateAuthorsTable extends Migration
{
public function up()
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('authors');
}
}
class CreateBooksTable extends Migration
{
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('books');
}
}
class CreateAuthorBookTable extends Migration
{
public function up()
{
Schema::create('author_book', function (Blueprint $table) {
$table->id();
$table->foreignId('author_id')->constrained()->onDelete('cascade');
$table->foreignId('book_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('author_book');
}
}
So in order to do this, I created a new command like this:
class custom-model extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'make:custom-model {modelName1} {modelName2} {--type}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Auto Relationship Maker';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
// make files
}
}
But I don't know how to make the necessary codes and files in the handle() method of this file.
So if you know, please let me know...

Laravel relationship design

I'm working on team management project.
I have a problem with doing relationships.
I want to display users in boards, but also want to look good and easy to read. I already designed relationships but when I saw JSON output of relationships, it was completely messed.
Is there some way how to display relationship data this way?
{
"id": 1,
"name: "Test",
"members": [
{
... user model here
"name": "Peter",
"email": "peter#peter.com",
}
]
}
My migrations:
Boards migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBoardsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('boards', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('boards');
}
}
Membership migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMembershipsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('memberships', function (Blueprint $table) {
$table->increments('id');
$table->integer('board_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('memberships');
}
}
EDIT:
Models
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Board extends Model
{
protected $fillable = ['name'];
public function members() {
return $this->hasMany(Membership::class)->with('user');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Membership extends Model
{
protected $fillable = ['board_id', 'user_id'];
protected $hidden = ['created_at', 'updated_at'];
public function user() {
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try to define the relationships in the models as a Many to Many one, i.e.:
class User
{
public function boards()
{
return $this->belongsToMany('App\Board', 'memberships', 'user_id', 'board_id');
}
}
class Board
{
public function members()
{
return $this->belongsToMany('App\User', 'memberships', 'board_id', 'user_id');
}
}
With that relations defined you don't really need a Membership Model if it has not additional fields, and you can write code like that:
User::find($id)->boards
Board::find($id)->members
Board::with('members')->find($id)
You could read also the documentation on Many to Many Relationships

hasMany model relation returns empty array. lLaravel Framework 5.5.40

This is my first time posting here, sorry if i input something incorrectly.
So i have Forums.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Forums extends Model
{
protected $table ='forums';
public $primaryKey='id';
public function section()
{
return $this->belongsTo(Section::class,'id');
}
}
and Section.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Section extends Model
{
public function forums()
{
return $this->hasmany(Forums::class,'section_id');
}
}
I fallowed tutorial in which it was shown that using
$section=Section::find($id)->forums;
i should get all the forums that had fk equal to section $id, however ir returns empty array.
I tried to output sql in terminal using:
$order = App\Section::find(2)->forums()->toSql()
where 2 is sections table id and got:
select * from `forums` where `forums`.`section_id` is null and `forums`.`section_id` is not
null"
so no wonder it returns empty array
however if i try to get section related to forum it works perfectly.
How could i fix this?
Changing hasmady to hasMany didn't fix it
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('Forums', function (Blueprint $table) {
$table->increments('id');
$table->string('Name');
$table->string('Description');
$table->integer('topics');
$table->integer('Comments');
$table->integer('Last_Post_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Forums');
}
}
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddToUsers extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('Forums', function (Blueprint $table)
{
$table->integer('Section_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
can't seem to find sections shema though i have it's table in database or is because that shema isn't in project folder, because im not getting errors that table or col can't be found?

How to create table migration in Laravel 5

I am working on a project where, I have been assigned a task to create user management for the application. But I have stuck on the table relationship and their migration.
Effort
I have these tables:
Users
user_id
username
password
Profiles
profile_id
user_id
firstname
lastname
email
Address
address_id
profile_id
address
city
state
country
pincode
Configurations
config_id
configuration_name
configuration_type
parent_id
Now I have to create model and migration for the same above structure. For this i have create/modify below model and migration class.
Model: User
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function profile()
{
return $this->hasOne('Profile','user_id');
}
}
Migration: 2014_10_12_000000_create_users_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('user_id');
$table->string('username');
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
Model: Profile
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
public function user(){
return $this->belongsTo('User');
}
public function address()
{
return $this->hasOne('Address','address_id');
}
}
Migration: 2016_02_26_101749_create_profiles_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('profile_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('user_id')->on('users')->onDelete('cascade');
$table->string('lastname')->nullable();
$table->string('firstname')->nullable();
$table->string('gender')->nullable();
$table->string('email')->unique();
$table->string('phonenumber', 20)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('profiles');
}
}
Model: Addess
namespace App;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
public function profile(){
return $this->belongsTo('Profile');
}
public function city() {
return $this->hasOne('Configuration', 'config_id');
}
public function state() {
return $this->hasOne('Configuration', 'config_id');
}
public function country() {
return $this->hasOne('Configuration', 'config_id');
}
}
Migration: 2016_02_26_102805_create_addresses_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAddressesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->increments('address_id');
$table->integer('profile_id')->unsigned();
$table->foreign('profile_id')->references('profile_id')->on('profiles')->onDelete('cascade');
$table->string('address')->nullable();
$table->integer('city')->unsigned();
$table->foreign('city')->references('config_id')->on('configurations')->onDelete('cascade');
$table->string('pincode')->nullable();
$table->integer('state')->unsigned();
$table->foreign('state')->references('config_id')->on('configurations')->onDelete('cascade');
$table->integer('country')->unsigned();
$table->foreign('country')->references('config_id')->on('configurations')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('addresses');
}
}
Model: Configuration
namespace App;
use Illuminate\Database\Eloquent\Model;
class Configuration extends Model
{
public function children() {
return $this->hasMany('Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('Configuration','parent_id');
}
public function address(){
return $this->belongsTo('Address');
}
}
Migration: 2016_02_26_104519_create_configurations_table.php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('configurations', function (Blueprint $table) {
$table->increments('config_id');
$table->string('configuration_name');
$table->string('configuration_type');
$table->string('parent_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('configurations');
}
}
Now, when I run php artisan migrate I am getting error that :
.
Please suggest me how to do that. I have to use same table structure and cannot modify it. If any further update require or I forgot something please let me know.
That happen because migration will try to migrate address table before configuration so it will not found the foreign key config_id you're referenced, so you could change the name of migrations files then the migration commad could pass the configurations_table migrate file first then the addresses_table migrate file, so just change :
2016_02_26_104519_create_configurations_table.php
To :
2016_02_26_102005_create_configurations_table.php
_____________^
After that you should run optimize command to regenerating optimized class loader :
php artisan o
And rerun php artisan migrate command now the problem should be solved.
Hope this helps.

Can't retrieve a one to many relationship in Laravel 4

I'm trying to get to a ProfileType through my User model, i.e. $user->profile->profiletype; I'm not able to retrieve an object, however. Basically, User hasOne Profile, and Profile belongsTo User and ProfileType. ProfileType hasMany Profile.
My table names are users, profiles and profile_types.
models/User.php
use Cartalyst\Sentry\Users\Eloquent\User as SentryUserModel;
class User extends SentryUserModel {
/**
* Indicates if the model should soft delete.
*
* #var bool
*/
protected $softDelete = true;
public function profile()
{
return $this->hasOne('Profile');
}
}
models/Profile.php
class Profile extends Eloquent {
protected $fillable = array('username', 'slug', 'completed');
/**
* #return
*/
public function user()
{
return $this->belongsTo('User');
}
public function profiletype()
{
return $this->belongsTo('ProfileType');
}
}
models/ProfileType.php
class ProfileType extends Eloquent {
/**
* #return
*/
public function profiles()
{
return $this->hasMany('Profile');
}
}
Profile and ProfileType migrations
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
// profile_types table
class CreateProfileTypesTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profile_types', function(Blueprint $table) {
$table->integer('id', true);
$table->string('name');
$table->string('slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('profile_types');
}
}
// profiles table
class CreateProfilesTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profiles', function(Blueprint $table) {
$table->integer('id', true);
$table->string('username');
$table->string('slug');
$table->boolean('completed');
$table->integer('user_id');
$table->integer('profile_type_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('profiles');
}
}
I think you may have found a bug with the way Laravel handles foreign keys. It should know that the foreign key of profile_types is profile_type_id but it's actually looking for profiletype_id.
So you can either change that column in your table so you don't have to worry about sending extra parameters each time you need another relationship on that table, or in your Profile model, you can make your function like this...
function profiletype
{
return $this->belongsTo('ProfileType', 'profile_type_id');
}
Then you should be able to find a user's profile type with...
$user = User::find(1);
echo $user->profile->profiletype->name;
echo $user->profile->profiletype->slug;

Categories