Search code examples
phplaravelpoint

laravel point eloquent releationship


I'm stuck at designing points.

I tried to make a point function, and the necessary functions are summarized as follows.

  1. Earn points according to posts or comments
  2. Display points earned from posts or comments
  3. The path where you can get points must be defined in advance (ex, you get points only when you write)

The relationship I got by summarizing the necessary functions above is as follows post, comment ... etc -> point -> pointType

pointType model

class PointType extends Model
{
    use HasFactory;

    protected $table = "point_types";
    protected $primaryKey = "id";
    protected $guarded = [];

    public function point()
    {
        return $this->hasMany('App\Models\Point', 'id', 'pointTypeID');
    }
}

point model

class Point extends Model
{
    use HasFactory;

    protected $table = "points";
    protected $primaryKey = "id";
    protected $guarded = [];

    public function pointable()
    {
        return $this->morphTo('pointable', 'pointable_type', 'pointable_id');
    }

    public function pointType()
    {
        return $this->belongsTo('App\Models\PointType','pointTypeID', 'id');
    }
}

Point Table

id|pointable_type |pointable_id|pointTypeID|memberID|created_at         |updated_at         |
--+---------------+------------+-----------+--------+-------------------+-------------------+
 1|App\Models\Post|          12|          1|       1|2021-06-13 13:22:51|2021-06-13 13:22:51|

PointType Table

id|type|point|
--+----+-----+
 1|write_post |    5|
 2|write_comment|    1|

After making the above I add points like below I was just trying to show I'm having a hard time creating that function.

Earn Point

        $post = Post::find($id);
        $post->points()->create([
            'memberID' => auth()->id(),
            'pointTypeID' => $pointType->id
        ]);

Display Point

        $userInfo = User::find($user->id);
//    dd($user->id);
        $points = array();
//        $points['totalPoint'] = $userInfo->points->pointable->sum('point');
//        $points['totalPoint'] = $userInfo->points->pointType->sum('point');
        $points = (object)$points;

I ask you a question.

  1. Is the point relationship design for the functions I want to implement right?

  2. How do I get the points and how do I modify the above codes to display the points to work properly?


Solution

  • I think what you're intending to do is something like:

    $userInfo = User::with('points.pointType')->find($user->id);
    $totalPoints = $userInfo->points->sum(function ($point) {
         return $point->pointType->point;
    });
    

    The idea here you are summing across all points based on their type rather than summing the type itself.