I have a table called "fields":
Schema::create('fields', function (Blueprint $table) {
$table->increments('id');
$table->string("label");
$table->string("name")->unique();
$table->text("options")->nullable();
$table->timestamps();
});
I want to have another table which simply stores the ids of some of the fields. I will call this default_fields.
I basically want a relationship or logic that allows me to grab these default_fields like I would with any other relation:
Schema::create('default_fields', function (Blueprint $table) {
$table->increments('id');
$table->integer("field_id");
});
How can I create a relationship that grabs all the fields whose id's are present in this table? I also want to be able to sync().
Would I just make a model for DefaultField and then do something like Field::whereIn('id', DefaultField::get()->pluck('id'))?
And then code my own sync() logic? Is there a super easy way to do this that I'm missing? I'd also like to be able to sort this like I would any other relation.
You can have a model Field that has this relationship:
public function defaultFields()
{
return $this->hasMany('App\DefaultField');
}
In you controller, you can fetch the Field with his related DefaultFields like:
$fields = Field::with('defaultFields')->get();
You can have a similar method field in your DefaultField model:
public function field()
{
return $this->belongsTo('App\Field');
}
In you controller, you can fetch the DefaultField with his parent Field:
$defaultFields = DefaultField::with('field')->get();
In your case, more productive will be 'is_default' boolean property in the fields table.
Related
So from my previous post, I was advised to start using Eloquent models, which I did.
My end goal, is to print out specific gifts, that belongs to that specific box.
Migrations:
gift_items:
public function up()
{
Schema::create('gift_items', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->float('unit_price');
$table->integer('units_owned');
});
}
gift_campaigns:
public function up()
{
Schema::create('gift_campaigns', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('user_foreignK')->constrained('users');
$table->integer('gift_item_count')->nullable();
$table->string('status');
$table->date('dispatch_date');
$table->date('delivery_date');
});
}
Pivot table:
public function up()
{
Schema::create('campaigns_gifts', function (Blueprint $table) {
$table->foreignId('gift_id')->constrained('gift_items');
$table->foreignId('campaign_id')->constrained('gift_campaigns');
});
}
Controller:
function box($id){
$data = Campaign::with('gifts')->where('id', $id)->get();
return view('DBqueries.boxView', ['data'=>$data]);
}
Error that I receive using this way:
Seems like the updated version is trying to call the gift_campaigns table id, instead of the pivots table campaign_id.
Once again, I need that Request $id would match the pivots table campaign_id, and print out all of the gifts that this specific id holds
First of all as I sense the campaigns_gifts is a pivot table for campaigns and gifts having a Many-to-Many relation. You are doing it completely against the conventions of Laravel.
You generally do not use a Model for pivot table.
You generally do not fetch data from the pivot table directly. Instead use the relation on one of the related Models.
Note: Laravel does allow a Model for a Pivot, and you can query the pivot table directly, just check the documentation.
The correct way:
Pivot
Make a pivot table (that you already have) with column gift_id and campaign_id. i.e., the convention for naming keys as [table_name_singular]_[primary_key_on_table]
Model
One each model, define relationship for the other data as:
Gift.php Model:
public function campaign() {
return $this->belongsToMany(Campaign::class, 'campaign_gift');
}
Campaign.php Model:
public function gifts() {
return $this->belongsToMany(Gift::class,'campaign_gift');
}
since gift have a hasMany relation, the gifts table must contain a foreign key to campaigns table named campaign_id (same as the one on pivot).
Controller
Now in your controller:
function box($id){
$data = Campaign::where('id',$id)->with('gifts')->get();
return view('DBqueries.boxView', ['data'=>$data]);
}
You don't need to tell Laravel which columns, tables etc are you referring to, as long as you follow the conventions, Laravel will magically do things that otherwise would have been much more painful.
I want to use morph relation in Laravel to access another model and also I didn't want use id as a foreign key to connect them, actually I want use uuid column on option table as foreign key in morph relation.
the table that I want to use morphrTo: (report table):
$table->id();
$table->unsignedBigInteger('exam_id')->nullable();
$table->foreign('exam_id')->references('id')->on('exams')->cascadeOnDelete();
$table->string('optionable_uuid');
$table->string('optionable_type');
$table->integer('spend_time')->default(0);
$table->timestamps();
and related morhMany table is: (option table)
$table->id();
$table->string('uuid');
$table->string('title');
$table->timestamps();
and my models same as below
// ReportModel
// OptionModelpublic function optionable()
{
return $this->morphTo();
}
// OptionModel
public function report()
{
return $this->morphMany(ExamReport::class,'optionable','optionable_type','optionable_uuid','uuid');
}
but output data in morph relation return null witch part is wrong and how can I fix it?
I must change morhTo model as same as below
public function optionable()
{
return $this->morphTo('optionable','optionable_type','optionable_uuid','uuid');
}
you can add diffrent primayKey in relation
public function report()
{
$this->primaryKey = "uuid";
return $this->morphMany(ExamReport::class,'optionable');
}
I have a League model and a Season model their respective migrations and relationships.
League migration and relations
Schema::create('leagues', function (Blueprint $table) {
$table->unsignedBigInteger("id")->primary();
$table->boolean("active");
$table->string("name");
$table->unsignedBigInteger("current_season_id")->nullable();
$table->timestamps();
});
public function current_season()
{
return $this->hasOne(Season::class);
}
Season migration and relations
Schema::create('seasons', function (Blueprint $table) {
$table->unsignedBigInteger("id")->primary();
$table->string("name");
$table->unsignedBigInteger("league_id");
$table->boolean("is_current_season");
$table->timestamps();
});
public function league()
{
return $this->belongsTo(League::class);
}
I have two vars with my models:
$league = League::find(1);
$season = Season::find(10);
With this line, I know automatically league_id in the Season model is filled with the $league->id
$season->league()->associate($league)->save();
I want do the inverse, and fill the current_season_id without doing:
$league->current_season_id = $season->id;
$league->save();
Is it possible?
Following the comments from #M Khalid Junaid, I think it´s better this way:
Remove current_season_id from League model.
Rewrite the current_season relation to this way:
public function current_season()
{
return $this->hasOne(Season::class)->where("is_current_season", true);
}
Now, in this way, I can access the current season of the league in the form: $league->current_season
Thank you.
You do not need $table->unsignedBigInteger("current_season_id")->nullable(); in leagues table, if you are using hasOne relationship, otherwise you need another type of relationship.
I'd strong recommend in seasons table, to use a foreign key declaration in your migration
$table->unsignedBigInteger("league_id");
$table->foreign( 'league_id' )->references( 'id' )->on( 'leagues' );
I have two model
Company:
public function slug(){
return $this->hasOne(Slug::class);
}
and Slug:
public function company(){
return $this->belongsTo(Company::class);
}
Slug table :
Schema::create('slugs', function (Blueprint $table) {
$table->increments('id');
$table->integer('company_id')->unsigned()->index()->nullable();
$table->foreign('company_id')->references('id')->on('companies');
$table->string('slug');
});
How can I store data into Slug table ?
I want store company id into company_id column and str_slug() of company name into slug column
Say you want to add a slug to a company with Id of 1.
This should help!
$company = App\Company::find(1);
$company->slug()->save(new App\Slug([$data]));
I don't think you need separated table for this. You will always have 1 value which probably will not change (due to SEO). But...
You can use observers https://laravel.com/docs/5.7/eloquent#observers
On created() method in your observer you can make it like that:
public function created(Company $company){
\App\Slug::create(['company_id' => $company->id, 'slug' => str_slug($company->name)]);
}
The same can be done if your slug is in company's table as field. Just use create() method instead and $company->slug = str_slug($company->name). And you can forget about them.
I have a table Task where it has creatorID and assignedTo. Both of them are foreign keys to my User table's primary key u_id. I'm trying to display the names of the creatorID and assignedTo but it is not working, it gave an error Trying to get property 'name' of non-object. Anyone able to spot whats wrong with my code? I'm opened to any suggestions or modifications to my models/tables thank you.
Task Table(Migration)
Schema::create('tasks', function (Blueprint $table) {
$table->increments('t_id');
$table->string('t_name');
$table->date('start_date');
$table->date('end_date');
$table->string('status');
$table->unsignedInteger('creatorID');
$table->unsignedInteger('assignedTo')->nullable();
$table->unsignedInteger('p_id');
$table->foreign('creatorID')->references('u_id')->on('users');
$table->foreign('assignedTo')->references('u_id')->on('users');
$table->foreign('p_id')->references('p_id')->on('projects');
$table->string('priority');
$table->timestamps();
});
User Table(Migration)
Schema::create('users', function (Blueprint $table) {
$table->increments('u_id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->string('status');
$table->string('picture');
$table->timestamps();
});
Task Model
public function users(){
return $this->belongsTo('App\User','u_id');
}
public function assignedTo(){
return $this->belongsTo('App\User','assignedTo');
}
User Model
public function tasks(){
return $this->hasMany('App\Task','u_id');
}
public function assignedTo(){
return $this->hasMany('App\Task','assignedTo');
}
Query
$ActiveTasks = Task::where('p_id',$projectID)->where('status','active')->get();
Blade File
#foreach($ActiveTasks as $task)
<p>{{$task->assignedTo->name}}</p> <<< NOT WORKING
#endforeach
You may need to update the assignedTo relationship in your Task model so that it knows to reference u_id instead of id:
public function assignedTo()
{
return $this->belongsTo(\App\User::class, 'assignedTo', 'u_id');
}
According to the docs:
If your parent model does not use id as its primary key, or you wish
to join the child model to a different column, you may pass a third
argument to the belongsTo method specifying your parent table's custom
key
https://laravel.com/docs/5.7/eloquent-relationships#defining-relationships
You should also check the tasks table to see if the assignedTo column is null for any of the saved records. Since you have the nullable attribute set, any records that had a null value in assignedTo would also produce the Trying to get property 'name' of non-object error when the relationship was accessed. If that's the case, you can define the relationship using the withDefault() method:
The belongsTo relationship allows you to define a default model that
will be returned if the given relationship is null. This pattern is
often referred to as the Null Object pattern and can help remove
conditional checks in your code
https://laravel.com/docs/5.7/eloquent-relationships#inserting-and-updating-related-models