Skip to content

Commit 8ddf93f

Browse files
committed
feat: allow configuration for reacts_model and reacts_id_column
1 parent 0d5c9e3 commit 8ddf93f

File tree

10 files changed

+328
-41
lines changed

10 files changed

+328
-41
lines changed

config/reactions.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,21 @@
88
*/
99
'table_name' => 'reactions',
1010

11+
/**
12+
* The name of the model that will be used to represent
13+
* the model (eg. User) that is reacting to a reactable model (eg. Post).
14+
*
15+
* If this is set to null, the package will attempt to use
16+
* the default user model for your application.
17+
*/
18+
'reacts_model' => null,
19+
20+
/*
21+
* This is the name of the column on the "reactions" table that will be used to
22+
* identify the "reacts_model" relationship.
23+
*
24+
* If this is set to null, the package will attempt to use the "user_id" column
25+
* on the "Reaction" model.
26+
*/
27+
'reacts_id_column' => null,
1128
];

migrations/2018_07_10_000000_create_reactions_table.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use Illuminate\Database\Migrations\Migration;
44
use Illuminate\Database\Schema\Blueprint;
55
use Illuminate\Support\Facades\Schema;
6+
use Qirolab\Laravel\Reactions\Helper;
67

78
/**
89
* Class CreateLoveLikesTable.
@@ -17,15 +18,17 @@ class CreateReactionsTable extends Migration
1718
public function up()
1819
{
1920
Schema::create(config('reactions.table_name', 'reactions'), function (Blueprint $table) {
21+
$userIdColumn = Helper::resolveReactsIdColumn();
22+
2023
$table->increments('id');
21-
$table->integer('user_id')->unsigned()->index();
24+
$table->integer($userIdColumn)->unsigned()->index();
2225
$table->morphs('reactable');
2326
$table->string('type')->nullable();
2427
$table->timestamps();
2528
$table->unique([
2629
'reactable_type',
2730
'reactable_id',
28-
'user_id',
31+
$userIdColumn,
2932
], 'react_user_unique');
3033
// $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
3134
});

src/Helper.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Qirolab\Laravel\Reactions;
4+
5+
class Helper
6+
{
7+
/**
8+
* Retrieve User's model class name.
9+
*
10+
* @return string
11+
*/
12+
public static function resolveReactsModel()
13+
{
14+
$userModel = config('reactions.reacts_model');
15+
if ($userModel) {
16+
return $userModel;
17+
}
18+
19+
return config('auth.providers.users.model');
20+
}
21+
22+
/**
23+
* Retrieve User's model column name in reactions table.
24+
*
25+
* @return string
26+
*/
27+
public static function resolveReactsIdColumn()
28+
{
29+
$userModel = config('reactions.reacts_id_column');
30+
if ($userModel) {
31+
return $userModel;
32+
}
33+
34+
return 'user_id';
35+
}
36+
}

src/Models/Reaction.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Qirolab\Laravel\Reactions\Models;
44

55
use Illuminate\Database\Eloquent\Model;
6+
use Qirolab\Laravel\Reactions\Helper;
67

78
class Reaction extends Model
89
{
@@ -14,14 +15,11 @@ class Reaction extends Model
1415
protected $table = 'reactions';
1516

1617
/**
17-
* The attributes that are mass assignable.
18+
* The attributes that aren't mass assignable.
1819
*
1920
* @var array
2021
*/
21-
protected $fillable = [
22-
'user_id',
23-
'type',
24-
];
22+
protected $guarded = [];
2523

2624
public function __construct(array $attributes = [])
2725
{
@@ -46,8 +44,9 @@ public function reactable()
4644
*/
4745
public function reactBy()
4846
{
49-
$userModel = config('auth.providers.users.model');
47+
$userModel = Helper::resolveReactsModel();
48+
$userIdColumn = Helper::resolveReactsIdColumn();
5049

51-
return $this->belongsTo($userModel, 'user_id');
50+
return $this->belongsTo($userModel, $userIdColumn);
5251
}
5352
}

src/Traits/Reactable.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Database\Eloquent\Builder;
66
use Qirolab\Laravel\Reactions\Contracts\ReactsInterface;
77
use Qirolab\Laravel\Reactions\Exceptions\InvalidReactionUser;
8+
use Qirolab\Laravel\Reactions\Helper;
89
use Qirolab\Laravel\Reactions\Models\Reaction;
910

1011
trait Reactable
@@ -26,9 +27,9 @@ public function reactions()
2627
*/
2728
public function reactionsBy()
2829
{
29-
$userModel = $this->resolveUserModel();
30+
$userModel = Helper::resolveReactsModel();
3031

31-
$userIds = $this->reactions->pluck('user_id');
32+
$userIds = $this->reactions->pluck(Helper::resolveReactsIdColumn());
3233

3334
return $userModel::whereKey($userIds)->get();
3435
}
@@ -136,7 +137,7 @@ public function reacted($user = null)
136137
{
137138
$user = $this->getUser($user);
138139

139-
return $this->reactions->where('user_id', $user->getKey())->first();
140+
return $this->reactions->where(Helper::resolveReactsIdColumn(), $user->getKey())->first();
140141
}
141142

142143
/**
@@ -196,15 +197,15 @@ public function scopeWhereReactedBy(Builder $query, $userId = null, $type = null
196197
try {
197198
$user = $this->getUser($userId);
198199
} catch (InvalidReactionUser $e) {
199-
if (! $user && ! $userId) {
200+
if (!$user && !$userId) {
200201
throw InvalidReactionUser::notDefined();
201202
}
202203
}
203204

204205
$userId = ($user) ? $user->getKey() : $userId;
205206

206207
return $query->whereHas('reactions', function ($innerQuery) use ($userId, $type) {
207-
$innerQuery->where('user_id', $userId);
208+
$innerQuery->where(Helper::resolveReactsIdColumn(), $userId);
208209

209210
if ($type) {
210211
$innerQuery->where('type', $type);
@@ -222,28 +223,18 @@ public function scopeWhereReactedBy(Builder $query, $userId = null, $type = null
222223
*/
223224
private function getUser($user = null)
224225
{
225-
if (! $user && auth()->check()) {
226+
if (!$user && auth()->check()) {
226227
return auth()->user();
227228
}
228229

229230
if ($user instanceof ReactsInterface) {
230231
return $user;
231232
}
232233

233-
if (! $user) {
234+
if (!$user) {
234235
throw InvalidReactionUser::notDefined();
235236
}
236237

237238
throw InvalidReactionUser::invalidReactByUser();
238239
}
239-
240-
/**
241-
* Retrieve User's model class name.
242-
*
243-
* @return \Illuminate\Contracts\Auth\Authenticatable
244-
*/
245-
private function resolveUserModel()
246-
{
247-
return config('auth.providers.users.model');
248-
}
249240
}

src/Traits/Reacts.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Qirolab\Laravel\Reactions\Contracts\ReactableInterface;
66
use Qirolab\Laravel\Reactions\Events\OnDeleteReaction;
77
use Qirolab\Laravel\Reactions\Events\OnReaction;
8+
use Qirolab\Laravel\Reactions\Helper;
89
use Qirolab\Laravel\Reactions\Models\Reaction;
910

1011
trait Reacts
@@ -19,10 +20,10 @@ trait Reacts
1920
public function reactTo(ReactableInterface $reactable, $type)
2021
{
2122
$reaction = $reactable->reactions()->where([
22-
'user_id' => $this->getKey(),
23+
Helper::resolveReactsIdColumn() => $this->getKey(),
2324
])->first();
2425

25-
if (! $reaction) {
26+
if (!$reaction) {
2627
return $this->storeReaction($reactable, $type);
2728
}
2829

@@ -44,10 +45,10 @@ public function reactTo(ReactableInterface $reactable, $type)
4445
public function removeReactionFrom(ReactableInterface $reactable)
4546
{
4647
$reaction = $reactable->reactions()->where([
47-
'user_id' => $this->getKey(),
48+
Helper::resolveReactsIdColumn() => $this->getKey(),
4849
])->first();
4950

50-
if (! $reaction) {
51+
if (!$reaction) {
5152
return;
5253
}
5354

@@ -64,10 +65,10 @@ public function removeReactionFrom(ReactableInterface $reactable)
6465
public function toggleReactionOn(ReactableInterface $reactable, $type)
6566
{
6667
$reaction = $reactable->reactions()->where([
67-
'user_id' => $this->getKey(),
68+
Helper::resolveReactsIdColumn() => $this->getKey(),
6869
])->first();
6970

70-
if (! $reaction) {
71+
if (!$reaction) {
7172
return $this->storeReaction($reactable, $type);
7273
}
7374

@@ -101,7 +102,7 @@ public function ReactedOn(ReactableInterface $reactable)
101102
public function isReactedOn(ReactableInterface $reactable, $type = null)
102103
{
103104
$isReacted = $reactable->reactions()->where([
104-
'user_id' => $this->getKey(),
105+
Helper::resolveReactsIdColumn() => $this->getKey(),
105106
]);
106107

107108
if ($type) {
@@ -123,7 +124,7 @@ public function isReactedOn(ReactableInterface $reactable, $type = null)
123124
protected function storeReaction(ReactableInterface $reactable, $type)
124125
{
125126
$reaction = $reactable->reactions()->create([
126-
'user_id' => $this->getKey(),
127+
Helper::resolveReactsIdColumn() => $this->getKey(),
127128
'type' => $type,
128129
]);
129130

tests/Stubs/Models/Profile.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Qirolab\Tests\Laravel\Reactions\Stubs\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Qirolab\Laravel\Reactions\Contracts\ReactsInterface;
7+
use Qirolab\Laravel\Reactions\Traits\Reacts;
8+
9+
class Profile extends Model implements ReactsInterface
10+
{
11+
use Reacts;
12+
13+
/**
14+
* The table associated with the model.
15+
*
16+
* @var string
17+
*/
18+
protected $table = 'users';
19+
20+
/**
21+
* The attributes that are mass assignable.
22+
*
23+
* @var array
24+
*/
25+
protected $fillable = [
26+
'name',
27+
];
28+
}

tests/TestCase.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Facades\File;
99
use Orchestra\Testbench\TestCase as Orchestra;
1010
use Qirolab\Tests\Laravel\Reactions\Stubs\Models\Article;
11+
use Qirolab\Tests\Laravel\Reactions\Stubs\Models\Profile;
1112
use Qirolab\Tests\Laravel\Reactions\Stubs\Models\User;
1213

1314
abstract class TestCase extends Orchestra
@@ -50,7 +51,7 @@ protected function publishPackageMigrations()
5051
*/
5152
protected function destroyPackageMigrations()
5253
{
53-
File::cleanDirectory(__DIR__.'/../vendor/orchestra/testbench-core/laravel/database/migrations');
54+
File::cleanDirectory(__DIR__ . '/../vendor/orchestra/testbench-core/laravel/database/migrations');
5455
}
5556

5657
/**
@@ -83,9 +84,9 @@ protected function getPackageProviders($app)
8384
*/
8485
protected function setUpDatabase()
8586
{
86-
include_once __DIR__.'/../migrations/2018_07_10_000000_create_reactions_table.php';
87-
include_once __DIR__.'/database/migrations/2018_07_10_000000_create_users_table.php';
88-
include_once __DIR__.'/database/migrations/2018_07_11_000000_create_articles_table.php';
87+
include_once __DIR__ . '/../migrations/2018_07_10_000000_create_reactions_table.php';
88+
include_once __DIR__ . '/database/migrations/2018_07_10_000000_create_users_table.php';
89+
include_once __DIR__ . '/database/migrations/2018_07_11_000000_create_articles_table.php';
8990

9091
(new \CreateReactionsTable())->up();
9192
(new \CreateUsersTable())->up();
@@ -151,4 +152,16 @@ public function createUser($attributes = [], $amount = null)
151152
$amount
152153
);
153154
}
155+
156+
public function createProfile($attributes = [], $amount = null)
157+
{
158+
return $this->factory(
159+
Profile::class,
160+
array_merge(
161+
['name' => $this->faker()->name],
162+
$attributes
163+
),
164+
$amount
165+
);
166+
}
154167
}

tests/Unit/ReactableReactionEventTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Support\Facades\Event;
66
use Qirolab\Laravel\Reactions\Events\OnDeleteReaction;
77
use Qirolab\Laravel\Reactions\Events\OnReaction;
8+
use Qirolab\Laravel\Reactions\Helper;
89
use Qirolab\Tests\Laravel\Reactions\TestCase;
910

1011
class ReactableReactionEventTest extends TestCase
@@ -41,7 +42,7 @@ public function it_can_fire_model_was_reacted_event_on_toggle_reaction()
4142
public function it_can_fire_reaction_deleted_and_model_was_reacted_event_on_change_reaction()
4243
{
4344
$this->article->reactions()->create([
44-
'user_id' => $this->user->getKey(),
45+
Helper::resolveReactsIdColumn() => $this->user->getKey(),
4546
'type' => 'like',
4647
]);
4748

@@ -55,7 +56,7 @@ public function it_can_fire_reaction_deleted_and_model_was_reacted_event_on_chan
5556
public function it_can_fire_reaction_deleted_and_model_was_reacted_event_on_change_reaction_via_toggle()
5657
{
5758
$this->article->reactions()->create([
58-
'user_id' => $this->user->getKey(),
59+
Helper::resolveReactsIdColumn() => $this->user->getKey(),
5960
'type' => 'like',
6061
]);
6162

@@ -68,7 +69,7 @@ public function it_can_fire_reaction_deleted_and_model_was_reacted_event_on_chan
6869
public function it_can_fire_reaction_was_deleted_event()
6970
{
7071
$this->article->reactions()->create([
71-
'user_id' => $this->user->getKey(),
72+
Helper::resolveReactsIdColumn() => $this->user->getKey(),
7273
'type' => 'like',
7374
]);
7475

0 commit comments

Comments
 (0)