0

I was wondering if you could help with a laravel relationship. I will try to explain as best I can.

I have a two tables:

Alerts

Schema::create('alerts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->float('price_low')->nullable();
            $table->float('price_high')->nullable();
            $table->json('conditions')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });

Conditions

DB::table('conditions')->insert([
            ['condition_value' => 'New'],
            ['condition_value' => 'Second Hand'],
            ['condition_value' => 'Ex Demo'],
]);

The condition field 'conditions' stores an array like this:

[{"condition_id": 1}, {"condition_id": 2}]

I am trying to define a relationship so I can do something like this:

$alerts = Alerts::with(['condition'])->where('user_id', $request->user()->id)->get();

My Alert model looks like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Alerts extends Model
{
    protected $casts = [
        'conditions' => 'array'
    ];
    

    public function user(){
        return $this->hasOne('App\User', 'id', 'user_id');
    }

    public function condition(){
        return $this->hasMany('App\Condition', 'id', 'conditions[condition_id]');
    }
}

but nothing is returned and I'm struggling to find an answer in the Laravel docs.

3 Answers 3

1

you can't get condition with relation you need to make it like this

public function getConditionsAttribute($conditions)
    {
        return App\Condition::whereIn('id',collect($conditions)->pluck('condition_id'))->get();
    }

and it will dynamically get with your data, and this will make it like with logic

Sign up to request clarification or add additional context in comments.

1 Comment

This is a good answer, but it needs to be elaborated to make it really good.
0

Alerts Model

Schema::create('alerts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->float('price_low')->nullable();
            $table->float('price_high')->nullable();
            $table->unsignedBigInteger('conditions')->nullable();
            $table->foreign('conditions')->references('id')->on('conditions');
            $table->softDeletes();
            $table->timestamps();
        });

Conditions model

Schema::create('conditions', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('condition_value')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });

insert data in Alerts table multiple records for a user_id ig a user id having multiple conditions such as:

user_id: 1 condition: 1

user_id: 1 condition: 2

user_id: 1 condition: 3

2 Comments

Where would you store the array in the alerts table?
if having a relationship between tables why to store array? save multiple records in that table. this will work with your existing relationship queries. user_id: 1 condition: 1 user_id: 1 condition: 2 user_id: 1 condition: 3 this is just an indication to save that in table.
0

Why aren't you modeling your relationship as a many to many between alerts and conditions?

I would use the following migrations:

Schema::create('alerts', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id'); // I assume your users table uses a bigIncrements for id
    $table->decimal('price_low')->nullable(); // Do not use FLOAT type for prices as is can cause rounding issues.
    $table->decimal('price_high')->nullable();
    $table->softDeletes();
    $table->timestamps();

    $table->foreign('user_id')->references('id')->on('users');
});

Schema::create('alert_condition', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('alert_id');
    $table->unsignedBigInteger('condition_id');
    $table->timestamps();

    $table->foreign('alert_id')->references('id')->on('alerts');
    $table->foreign('condition_id')->references('id')->on('conditions');
});

Schema::create('conditions', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('value');
    $table->timestamps();
});

To insert the conditions you now have to use:

DB::table('conditions')->insert([
    ['value' => 'New'],
    ['value' => 'Second Hand'],
    ['value' => 'Ex Demo'],
]);

The only additional thing that you need to be aware is that each association between an alert and a condition will be a record in the alert_condition pivot table with the foreign keys of the two models that you want to connect.

This can be done in a number of ways. To stick with your previous conditions inserts you can use:

DB::table('alert_condition')->insert([
    ['alert_id' => 1, 'condition_id' => 1],
    ['alert_id' => 1, 'condition_id' => 2],
    ['alert_id' => 2, 'condition_id' => 1],
    // ...
]);

I would then use the following models:

Alerts Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;

class Alerts extends Pivot
{
    use SoftDeletes;

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function conditions()
    {
        return $this->belongsToMany(Condition::class);
    }
}

Condition Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Condition extends Model
{
    public function alerts()
    {
        return $this->belongsToMany(Alert::class);
    }
}

Then in your controller or wherever you need you can query like this:

// Assuming your authentication works with the User model and that model
// has a correct hasMany alerts() relationship.
$user = Auth::user();

// This would print out all the alerts for the current logged in user
// and each alert will contain the conditions values associated to that alert.
dump($user->alerts()->with('conditions')->get());

// If you also need to keep the user with its data, just eager load the relations
dump($user->load('alerts.conditions'));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.