Referencing two models at the same time - eloquent

I have a booking table which points to bookings on either room_bookings or restaurant_bookings table a room or restaurant table the migration are
Booking:
Schema::create('bookings', function (Blueprint $table) {
$table->increments('id');
$table->morphs('booking');
$table->morphs('business');
$table->boolean('status');
}
room_bookings:
Schema::create('room_bookings', function (Blueprint $table) {
$table->increments('id');
$table->string('from');
$table->string('to');
}
restaurant_bookings:
Schema::create('restaurant_bookings', function (Blueprint $table) {
$table->increments('id');
$table->string('table_no');
}
Restaurant:
Schema::create('restaurants', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
}
Room:
Schema::create('rooms', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('number_of_rooms');
}
In previous projects I used to define single relationship to the model. I want to save the booking id ,class and room/restaurants id and class and class name on the table.
Before I defined realtionship on single class as
$boking = Booking::findOrFail($id);
//Defined relationsip on the model as booking()
$room->booking()->create($data)
The Models are as follows
Business.php
class Booking extends Model
{
public function bookings()
{
return $this->morphTo();
}
public function business()
{
return $this->morphTo();
}
}
on Room.php and Restaurant.php
public function booking()
{
return $this->morphMany(Booking::class, 'booking');
}
public function business()
{
return $this->morphMany(Booking::class, 'business');
}

Related

Can't add foreign key constraints on Laravel5.5

i created several tables :
KEYNEEDS TABLE :
public function up()
{
Schema::create('keyneeds', function(Blueprint $table)
{
$table->integer('id', true);
$table->integer('segment_id')->index('FK_KN_SEGMENT');
$table->integer('design_id')->index('FK_KEYNEEDS_DESIGN');
$table->integer('admin_id')->index('FK_KN_ADMIN');
$table->string('kntextcolor', 191)->nullable();
$table->string('kntextcolorhover', 191)->nullable();
$table->string('knbgcolor', 191)->nullable();
$table->string('knbgcolorhover', 191)->nullable();
$table->string('knhvize', 191)->nullable();
$table->timestamps();
$table->softDeletes();
$table->engine = 'InnoDB';
});
}
DESIGNS TABLE :
public function up()
{
Schema::create('designs', function(Blueprint $table)
{
$table->integer('id', true);
$table->string('design', 191)->nullable();
});
}
I also added foreign key constraints
public function up()
{
Schema::table('keyneeds', function(Blueprint $table)
{
$table->foreign('design_id', 'FK_KEYNEEDS_DESIGN')->references('id')->on('designs')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('admin_id', 'FK_KN_ADMIN')->references('id')->on('admins')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('segment_id', 'FK_KN_SEGMENT')->references('id')->on('segments')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
i have this SQL error when i try to migrate the database:
Can not add external index constraints (SQL: alter table `keyneeds` add constraint` FK_KEYNEEDS_DESIGN` foreign key (`design_id`) references`
igns(id`) on delete RESTRICT on update RESTRICT)
The answer was given by Jonas Staudenmeir :
public function up()
{
Schema::create('designs', function(Blueprint $table)
{
$table->integer('id', true);
$table->string('design', 191)->nullable();
$table->engine = 'InnoDB';
});
}

Sort articles by most comments

I have two tables articles and comments. The have one to many relationship. An article has many comments and the other side a comment is belongs to an article. Now I want to sort all articles according to most comments.
Here is the table schema:
articles
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->integer('category_id')->unsigned();
$table->text('body');
$table->string('tags');
$table->string('slug')->unique();
$table->string('image');
$table->date('published_at');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
comments
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('blog_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->integer('comment_id')->nullable(); //parent comment's id if any
$table->text('message');
$table->timestamps();
$table->foreign('blog_id')
->references('id')
->on('articles')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')
->on('users');
});
}
Here is the relationship code:
Article
/**
* An article has many comments
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
Comment
/**
* A comment is belongs to an article
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function article()
{
return $this->belongsTo('App\Article');
}
Any help will be appreciable.
I preferred the solution in Eloquent way. If not possible other way will also OK.
You can try as:
Article::withCount('comments')->orderBy('comments_count')->get();
withCount() method is used when you want to count the number of results from a relationship without actually loading them, which will place a {relation}_count column on your resulting models.

EF different mapping for an entity based on inheritance

I have two entities (tables) Action and ActionLog. The ActionLog is derived from Action. I need to map entity Action to table Action when it is used alone and map it to table ActionLog when it is used inside an inheritance relationship.
Entities:
Action entity properties:
Action_Property1
Action_Property2
Action_Property3
ActionLog entity properties:
All the inherited properties from Action entity
ActionLog_Property1
Tables:
Action table columns:
Action_Property1
Action_Property2
Action_Property3
ActionLog table columns:
Action_Property1
Action_Property2
Action_Property3
ActionLog_Property1
Is this possible using EF6 Code First mapping in a single context?
Edit 1:
I try to be more explicit. I need something like this:
using(var ctx = new DbContext())
{
var action = new Action
{
Action_Property1 = 1,
Action_Property2 = 2,
Action_Property3 = 3
};
ctx.Actions.Add(action);
ctx.SaveChanges();
}
The lines above should write the Action entity to Action table.
using(var ctx = new DbContext())
{
var actionLog = new ActionLog
{
Action_Property1 = 1,
Action_Property2 = 2,
Action_Property3 = 3,
ActionLog_Property1 = 1
};
ctx.ActionLogs.Add(actionLog);
ctx.SaveChanges();
}
The lines above should write the ActionLog entity to ActionLog table.
Yes, it's possible. Using Mapping the Table-Per-Concrete Class (TPC) Inheritance
it can do so
public class InheritanceMappingContext : DbContext
{
public DbSet<Action> Action { get; set; }
public DbSet<ActionLog> ActionLog { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ActionLog>().Map(m =>
{
m.MapInheritedProperties(); // add inherited property to actionLog
m.ToTable("ActionLog");
});
modelBuilder.Entity<Action>().Map(m =>
{
m.ToTable("Action");
});
}
}
Sure, map your base class:
public class YourBaseClassMapping<T> : EntityTypeConfiguration<T> where T : YourBaseClassEntity
{
protected YourBaseClassMapping()
{
HasKey(x => x.Id);
...
}
}
and then map inherited class:
public class InheritedClassMapping<T> : EntityTypeConfiguration<T> where T : InheritedClassMapping
{
public InheritedClassMapping()
{
// new mapping for inherited class
}
}
and add both mappings to DbModelBuilder as other mappings:
public class YourDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new YourBaseClassMapping());
modelBuilder.Configurations.Add(new InheritedClassMapping());
}
}

Laravel 5 Eloquent Relationship - Has Many Though

I have three models.
Study
Site
Unit
Study Has and belongs to many Sites and each site that belongs to Study again has and belongs to many Unit. Please see the following drawing.
http://tinypic.com/r/ojhx0g/8
How I achieve this using Laravel 5 Eloquent Relationships.
It sounds like you have many-to-many relationships between Study->Site and Site->Unit. You can read the Laravel documentation about many-to-many relationships here.
Models
Here are the relevant functions you'll need for Eloquent to recognize the relationships.
class Study extends Model {
// If you named your table differently (like 'studies'), specify that here
protected $table = 'studys';
// This assumes a pivot table named 'site_study', if you named yours
// differently you can pass in into the belongsToMany() function as the
// second parameter.
public function sites() {
return $this->belongsToMany('App\Site');
}
}
class Site extends Model {
protected $table = 'sites';
public function studies() {
return $this->belongsToMany('App\Study');
}
public function units() {
return $this->belongsToMany('App\Unit');
}
}
class Unit extends Model {
protected $table = 'units';
public function sites() {
return $this->belongsToMany('App\Site');
}
}
Then, to access the Sites belonging to a Study you would do this:
$sites = Study::find(1)->sites;
Pivot Table Migrations
Laravel expects pivot tables to be named like 'alpha_beta' where alpha and beta are the singular model names in alphabetical order. So your migrations for the pivot tables would look like this:
class CreateSiteStudyTable extends Migration {
public function up() {
Schema::create('site_study', function(Blueprint $table)) {
$table->integer('site_id')->unsigned();
$table->foreign('site_id')->references('id')->on('sites');
$table->integer('study_id')->unsigned();
$table->foreign('study_id')->references('id')->on('studys'); // or whatever you named it
$table->unique(['site_id', 'study_id']);
$table->timestamps();
});
}
public function down() {
Schema::drop('site_study');
}
}
class CreateSiteUnitTable extends Migration {
public function up() {
Schema::create('site_unit', function(Blueprint $table)) {
$table->integer('site_id')->unsigned();
$table->foreign('site_id')->references('id')->on('sites');
$table->integer('unit_id')->unsigned();
$table->foreign('unit_id')->references('id')->on('units');
$table->unique(['site_id', 'unit_id']);
$table->timestamps();
});
}
public function down() {
Schema::drop('site_unit');
}
}
You can read about Foreign Keys in Laravel here.
you have to create 3 models study, site and unit as per you diagram study has many sites and sites has many units, in you diagram study don't have direct relation with units your eloquent models will be like this.
class Study extends Model {
public function sites(){
return $this->hasMany('App\Site');
}
}
class Site extends Model {
public function units(){
return $this->hasMany('App\Unit');
}
public function study(){
return $this->belongsTo('App\Study');
}
}
class Unit extends Model {
public function sites(){
return $this->belongsTo('App\Site');
}
}

model is autopopulated when using EF 3.5 partial class

I'm using EF 3.5 and I've created partial classes with the same name as my tables and EF generated classes.
public partial class Region
{
public Region()
{
}
public Region(string name)
{
this.RegionName = name;
}
public bool Save()
{
try
{
using (var context = new PhonebookEntities())
{
context.AddToRegions(this);
context.SaveChanges();
}
return true;
}
catch (System.Exception)
{
return false;
}
}
}
When I'm create and save a new Region
var region = new Region("TestRegion");
region.Save().ShouldBeTrue();
I get an exception when I save because the region entity is autopopulated with RegionId = 0, which is setup in the db to autoincrement.