Replies: 16 comments
-
Hrm.. so it seems like I stumbled upon something that works.. although it seems wrong somehow but it does work In my User nova resource I added this field:
Then I created a new resource like this:
And finally in my User mode I added this relation
And now I can get a list of users that any user has "liked"... cool Thoughts? Now I would like to be able to get the inverse relation but I don't know how Meaning, if I click on a User that has been liked by another user, I would like to be able to display a list of "Users liked by" Do you know how could I achieve this? Thanks! |
Beta Was this translation helpful? Give feedback.
-
Never thought about creating Nova package for this one. If you'll create a public Nova wrapper package - I'll be happy to promote it in this repo. You could try to get this information from the user reactions and iterate through it, something like: $user->viaLoveReacter()->getReactions(); But it would be not optimal way if there is a lot of data. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Yes that's what I was thinking.. the terminology is making my head spin though. Shouldn't it be I feel like this would be a nice addition to your package.. having the ability to return the models that have reacted to you.. so as you put it.. Any chance you could take a stab at writing this query since you're so familiar with the inner workings? I'd be happy to test it out to confirm that it works |
Beta Was this translation helpful? Give feedback.
-
Pretty busy this days, launching new service: https://yhype.me/ 😄 |
Beta Was this translation helpful? Give feedback.
-
Thanks @antonkomarev and good luck with your launch! I wrote this and it seems to work! It was quite simple just had to many two small modifications to the What do you think? Did I miss something? public function scopeWhereReactedTo(
Builder $query,
ReacterableInterface $reacterable,
?string $reactionTypeName = null
): Builder {
return $query->whereHas('loveReacter.reactions', function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
});
}
public function scopeWhereNotReactedTo(
Builder $query,
ReacterableInterface $reacterable,
?string $reactionTypeName = null
): Builder {
return $query->whereDoesntHave('loveReacter.reactions', function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
});
} If you like it and it seems to work then maybe you could add it? Or do you want me to submit a PR? |
Beta Was this translation helpful? Give feedback.
-
Very close to the correct one. Instead of Reacterable (who reacts) you should bypass Reactable (on whom react) model as second argument: public function scopeWhereReactedTo(
Builder $query,
ReactableInterface $reactable,
?string $reactionTypeName = null
): Builder {
return $query->whereHas('loveReacter.reactions', function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
});
}
public function scopeWhereNotReactedTo(
Builder $query,
ReactableInterface $reactable,
?string $reactionTypeName = null
): Builder {
return $query->whereDoesntHave('loveReacter.reactions', function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
});
} |
Beta Was this translation helpful? Give feedback.
-
You could create a PR. If it will have tests similar as These methods should be in |
Beta Was this translation helpful? Give feedback.
-
Thanks for the tips @antonkomarev Do you know if it's also possible to easily retrieve the reaction date when using Right now it returns the users that have reacted to/by the specfied reaction type.. but I'm not seeing an easy way to also retrieve more details about that reaction, namely the datetime it occurred at |
Beta Was this translation helpful? Give feedback.
-
Since it returns Eloquent Builder you could get collection and filter it, but it wouldn't be an optimal way. Another approach is to create additional scope methods with datetime range parameters, but I think it will become too complicated. Maybe some kind of services may solve that. |
Beta Was this translation helpful? Give feedback.
-
You may add extra scope: public function scopeWhereWasReactedBetweenDates(
Builder $query,
DateTimeImmutable $fromDateTime,
DateTimeImmutable $toDateTime
): Builder {
return $query->whereHas('loveReactant.reactions', function (Builder $reactionsQuery) use ($fromDateTime, $toDateTime) {
$reactionsQuery->whereBetween('created_at', [$fromDateTime, $toDateTime]);
});
} And then use both scopes: $toDate = new DateTimeImmutable();
$fromDate = $toDate->modify('-1 DAY');
$articlesReactedByUser = Article::query()
->whereReactedBy($user)
->whereWasReactedBetweenDates($fromDate, $toDate)
->get(); I haven't tested it, but in theory this should work. Better than collections filtering, but not so fast as well designed raw SQL query. |
Beta Was this translation helpful? Give feedback.
-
I misunderstood you. You don't need to find reactable models within dates, but want to know when exactly user reacted to each of them. Interesting question, I don't have answer on it yet. |
Beta Was this translation helpful? Give feedback.
-
Yes that's right.. although those extra scopes could come in handy as well so thanks for sharing : ) I was just hoping that the date of the reaction could be easily retrieved when fetching models that have been reacted to |
Beta Was this translation helpful? Give feedback.
-
@antonkomarev I know this won't be super useful and would lend itself to a n+1 problem.. but this is the workaround I came up with to retrieve the raw reaction from the db table in order to expose the datetime of the reaction itself which is useful in my case It would be nice if a future version could more easily expose/include the date of each reaction, possibly as a pivot value? Also I hope the new query scopes you have a draft of can be added to the next release too : ) $rawReaction = (new Love)->getRawReaction($user, User::find(request('viaResourceId')), 'LIKE'); <?php
namespace App\Helpers;
use App\Models\LoveReaction;
class Love
{
public function getRawReaction($reactable, $reacterable, $reactionType)
{
$rawReaction = LoveReaction::where('reactant_id', $reactable->love_reactant_id)
->where('reacter_id', $reacterable->love_reacter_id)
->where('reaction_type_id', config('love.reaction-types')[$reactionType])
->first();
return $rawReaction;
}
} <?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class LoveReaction extends Model
{
protected $table = 'love_reactions';
} |
Beta Was this translation helpful? Give feedback.
-
Thanks for sharing it @vesper8! I've just fixed terminology in 2nd code block to follow same naming convention with the package. We need to think more about exposing datetime out of the box. I suppose it will be better to create separate issue for it, because we might lose it here. This one was initially about the Laravel Nova support. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the edit! I've edited the code in my project to reflect your changes too. I always struggle a bit whenever I try to wrap my mind around the terms reacterable and reactable. Regarding Nova.. here's a code snippet that showcases how I'm showing the date on my user resource. It's not that clean but it works. As you can see I've adopted Laravel Love fully.. actually there are a few other reaction types not shown here that I'm using. I found the scopes so useful that I'm using it heavily as a replacement for setting up pivot tables Text::make('Date', function ($user) {
$rawReaction = null;
switch (request('viaRelationship')) {
case 'LikedUsers':
$rawReaction = (new Love)->getRawReaction($user, User::find(request('viaResourceId')), 'LIKE');
break;
case 'LikedByUsers':
$rawReaction = (new Love)->getRawReaction(User::find(request('viaResourceId')), $user, 'LIKE');
break;
case 'DislikedUsers':
$rawReaction = (new Love)->getRawReaction($user, User::find(request('viaResourceId')), 'DISLIKE');
break;
case 'DislikedByUsers':
$rawReaction = (new Love)->getRawReaction(User::find(request('viaResourceId')), $user, 'DISLIKE');
break;
case 'FavoritedUsers':
$rawReaction = (new Love)->getRawReaction($user, User::find(request('viaResourceId')), 'FAVORITE');
break;
case 'FavoritedByUsers':
$rawReaction = (new Love)->getRawReaction(User::find(request('viaResourceId')), $user, 'FAVORITE');
break;
case 'BlockedUsers':
$rawReaction = (new Love)->getRawReaction($user, User::find(request('viaResourceId')), 'BLOCK');
break;
case 'BlockedByUsers':
$rawReaction = (new Love)->getRawReaction(User::find(request('viaResourceId')), $user, 'BLOCK');
break;
default:
dd(sprintf('Unhandled viaRelationship %s', request('viaRelationship')));
}
if ($rawReaction) {
return (new Timezone)->convertToLocal($rawReaction->created_at);
}
// dd(request()->all(), $this->toArray());
return 'n/a';
}), User.php public function blockedByUsers()
{
return $this->whereReactedTo($this, 'Block');
}
public function blockedUsers()
{
return $this->whereReactedBy($this, 'Block');
}
public function likedByUsers()
{
return $this->whereReactedTo($this, 'Like');
}
public function likedUsers()
{
return $this->whereReactedBy($this, 'Like');
}
public function dislikedByUsers()
{
return $this->whereReactedTo($this, 'Dislike');
}
public function dislikedUsers()
{
return $this->whereReactedBy($this, 'Dislike');
}
public function favoritedByUsers()
{
return $this->whereReactedTo($this, 'Favorite');
}
public function favoritedUsers()
{
return $this->whereReactedBy($this, 'Favorite');
} I'll open another issue for the date exposure |
Beta Was this translation helpful? Give feedback.
-
I see that you have a laravel-ban-nova package so maybe you have an idea how I can use Laravel Love with Laravel Nova?
Basically I have a reaction type called "like" and I want to show the users that a user has liked inside Laravel Nova
And I am unsure how to go about achieving this.
I would like to use Nova's HasMany field but I don't know how to defined the
liked
relationship on my User modelCould you offer some assistance please?
Beta Was this translation helpful? Give feedback.
All reactions