Get all rows user is authorised to see - laravel

I have Book and Page models.
Users may be allowed to see individual pages from the book or the whole book.
For example, I have the following pages table:
id | page_number | book_id
1 1 4
2 2 4
3 3 4
User A has permissions to see only pages 1 and 2, how can I fetch from the database only the pages he has permissions to view (i.e., 1,2)
Also, User B has permission to see the whole book (the permission assigned to the book record, not for all pages in the book), so he should get pages 1-3 (and maybe future pages that may be added into the book).
Is it possible to implement this in Laravel? Maybe with bouncer or Laravel-permissions?

Probably easiest to keep this simple: I wouldn't look to a package to implement, I think perhaps just a couple of relationship tables on the User where the pages or books are the models that user is authorized to see:
book_user, where you have a user_id and a book_id
And
page_user where you have a page_id and user_id plus a book_id on the page model itself so that you can pull the pages for a specific book that the user is authorized to see.
Make your many to many relationships on the User along with a pivot for book_id on the pages relationship, and then pull the appropriate authorization after you have the current user. For example:
// $user set above - might be $user = \Auth::user() or from an id from a form
if(isset($user->books->find($someBookID))
$book = Book::find($someBookID);
// pages below might be related to a specific book: pages->where('book_id', $something)
elseif(count($user->pages->pluck('page_id'))
$pages = Page::whereIn('page_number', $user->pages->pluck('page_id')->toArray())
And then send these to your view based on a bit more logic within the if-checks above.
This is really just pseudo code, as I don't know much about the rest of your codebase, but hopefully the idea behind this will give you an easy solution to what you've asked.

Related

Handle model dependencies in Laravel Repository Pattern

I'm discovering the Repository Pattern for my Laravel project but I have to say that I'm a bit lost once a model has several dependencies and the examples on the web are always basic and don't answer the question for more complex use cases.
Let's imagine a user on my app. He can have badges, he has different things on the app that will be slightly modified when he first performs the action (when he first sees the comments, I tell him once the different things he can do, etc), he has several "counters" to record the number of comments he made, the number of friends he invited, without having to count each entry each time.
My database looks like this:
users table:
id
pseudo
name
password
...
badges table:
user_id
badge1_xxxxxx
badge2_xxxxxx
...
I have a very limited number of badges so I decided to create a column for each of them and as soon as a user wins a badge, I get his entry (in OneToOne relationship) and I indicate that the badge in question has been won.
onboarding table:
user_id
seen_comments (boolean)
seen_results (boolean)
...
As you can see, I store each action I'd like the user to do in different columns and as soon as he has done one and I've been able to modify my app accordingly (by showing him an arrow, etc), I put the column in question to true.
user_counters table:
user_id
count_comments
count_invited_friends
...
I don't consider a user to be a user if he doesn't have an entry in each of the tables (I could have done everything in one table but the users table seemed to me to become huge). The only relationship used is OneToOne between the user and the table in question.
Should I do this ?
class UserRepository {
public function register($data) {
// Create the user
$user = User::create($data);
// Create all its dependencies which are required if I want to consider the user as fully registered in my DB
$user->badges()->create();
$user->onboarding()->create();
$user->counter()->create();
// Return the user
return $user;
}
}
Or should I create a Repository for each of these elements and create the entire user in a UserService ?
How far should I separate things and when does it become overkill?
Is there something that I don't understand in concept of Repository ? If so, could you give me some links that you found useful because I feel like I ran out of ideas for search keywords.
Thanks

In need of a logic to create comments in laravel

Ok so the basis is that I want to be able to have comments on each of my post. The comments will have a reply button for each. It’s not multi threaded so one comment will have many replies. Those replies won’t have replies. Also I want to be able to like and dislike a comment/reply. All of this will not be bind to the user model or any of such. The public visitors will be able to add comments and reply to comments but the approval is needed.
So here is the logic I got so far. Am I on the right track here (hoping this post may help someone else as well):
So i create aComment model. And then create a table named comments.
And I create a model named Reply and a table named replies
And finally, a model name Like and it’s table likes
So the relationship is:
comments will have many replies and replies belongs to one comment
replies & comments will have many likes.
And now for the logic:
I will use AJAX to call the store function on the CommentController to store comments. And I will call the store function on the ReplyController to store the replies. As for the likes, LikeController store function will store the likes for the comment and reply.
Here is the table structure:
Comments table
id
post_id
name
email
comment
approved
timestap
Replies table
id
comment_id
name
email
comment (or reply)
approved
timestamp
Likes table
id
comment_id
reply_id
like
dislike
timestamp
Now what I do not understand is, likes table. Is it right to have comment_id and reply_id and also like and dislike?
I could call the store function everytime someone clicks the like or dislike and have it stored in the table and update the column if it is a reply or a comment by it’s id to the respective id columns. Is the logic right?
Also, if you guys have any suggestions or better and efficient way of doing this, please let me know.
This is getting too long so I’ll just leave it here.
Edit
Also forgot to mention that I am not sure how I will be taking the amount of likes from db to blade and count it. Not with the current structure mentioned above. Also, how to check and see if the person already liked. And if so, don’t let them like again or dislike again. A liked person can not dislike. They can do only one thing.
I would definitely recommend associating comments, replied and likes to a User which you are pretty much already doing with comments and replies.
There are ways that you could have a "liking" system that would allow guest usage, however, this would be very easy to get around and ultimately make your "like" stats useless.
An example DB structure going forward would be:
comments and replies
id
post_id // or comment_id if on the replies table
user_id
body
approved
( "_at" dates)
likes
id
likeable_id // id of the comment or reply
likeable_type // Comment or Reply
user_id
liked (boolean)
("_at" dates)
The likes table is setup to be used as a Polymorphic relationship e.g. in your Comment model:
public function likes()
{
return $this->morphMany(Like::class, 'likeable');
}
Then to add a like you would have something like:
$like = new Like(['user_id' => auth()->user()->id, 'liked' => true]);
$comment->likes()->save();
There are many different ways you would then check if the current auth user has liked a post, one example would be to have a separate relationship so that you can eager load the results:
public function authUserLike()
{
return $this->morphOne(Like::class, 'likeable')->where('user_id', auth()->id());
}
Then if the auth_user_like is null they haven't already liked that comment.
I don't see any need of the Replies Table just use parent_id in comments table. This tutorial might help you get started Nesting Comments in Laravel

Correct Many to Many friends relationship for users

What is the correct way to relate users in parse to one another as friends?
I also want users to be able to query other users but not see all fields, like emails. Is there a way I can create a view on the users table with cloud code, and only return this to the client code?
I was thinking I can create a friends table that will have two columns with 2 pointers, 1 for each user.
thanks for any advice.
I was thinking I can create a friends table that will have two columns with 2 pointers, 1 for each user.
I'll do that too, with a status column to handle pending, blocked...etc
I also want users to be able to query other users but not see all fields, like emails.
You have to add a privateData column on user with ACL restricted to owner only, which would contain private infos such as emails...etc

Using GORM efficiently to retrieve join data - Grails 2.3

I have User, and Follow Domain class that construct the Follower, Following relationship like Twitter. When my User visits another User's page, and click on their Follower list. I pop-up the list of the visited person's follower list, and then show a button in front of it that is labeled "Follow" or "Unfollow" depending on if you already following that person. So I do it the following way, but I'm not sure if this is efficient or maybe there is a better way of doing it. In order to make it efficient, I only retrieve 20 follower at a time and allow pagination.
> example of pop-up:
> ----------------------------------------------
> alex [follow]
> dave [unfollow]
> sarah[follow]
> paul [follow]
> ----------------------------------------------
Follow domain class has:
// The person to follow
User follow
// The person who is following the follow
User follower
// The status of the relationship if removed or still following
boolean status
User domain class is the typical Spring Security User class with a bunch of extra fields like locations and etc.
In my controller when I receive a request for follower list I do the following.
def visitedUser = User.get(visitedUserId)
// get the list of top 20 followers of this user
def followerList = Follow.findAllByFollow(visitedUser, [max:20])
// get the list of all people current user follow who is in the 20 follower list
def mutualFollow = Follow.findAllByFollowerAndFollowInList(currentUser, followerList)
Now I have the list of all the followers in profile of the person I'm visiting, and also the list of those who are mutual. Then I pass both to my GSP and while loop through the followerList in GSP, I compare the id of that follower, if the follower exist in my mutualFollow list I tweak the button to "unfollow" otherwise I keep the button as follow.
One step further to optimize this is to user projection to only retrieve the id of the mutualFollow instead of the whole USER domain object, but since USERs coming back are proxied and they have wrapper around them, I'm not sure that makes a big difference. Because All I retrieve is the id.
I appreciate any suggestion to improve this approach or an alternative. Thanks
I decided to use HQL and only retrieve the necessary info of those USERs within the follow list, and then I did a join to get the mutual people they both follow. And used that in the GSP page. Here is the simplified solution in SQL:
SELECT Ur.follow_id, Urs.follow_id as mutual FROM (SELECT * FROM FOLLOW WHERE FOLLOWER_ID=1)as Urs
RIGHT JOIN (SELECT * FROM FOLLOW WHERE FOLLOWER_ID=3) as Ur
ON Urs.follow_id=Ur.follow_id order by Ur.follow_id;

Help with Codeigniter and MVC model pattern

I am creating a site much like a wordpress blog whereby the front page will display a post loop: with the post_summary, author info, and tags.
I have four tables:
posts | users | tags | tag relationships
to display all the results i would need to do multiple JOINs for in the SELECT statement
However, to stay with the MVC pattern, there should be a model for each table ( or object ?). So my question is: If I were doing a SELECT all, how would I do this and still keep with the MVC pattern?
To get all the required info for the post, I need the author_id to get my info from the users table AND I need the post_id to get the tags (and so on). If all of my queries are in different Models, what is the best way to perform the query?
Do I make one Model that does all of the JOINS and just use it? Should I load Models from the view? Or should I do additional query work in the Controller?
I think you have a misunderstanding of the purpose of Models. Models are to deal with data in your database and are not limited to 1 table per model. If you are creating a blog, you will really just need one model. Take a look at the tutorial on the codeigniter website, http://codeigniter.com/tutorials/watch/blog/, and reread the user guide for models, http://codeigniter.com/user_guide/general/models.html .
You may be getting MVC confused with an ORM
Do not make a model for the joins. As answered by #Johnny already, a Model and a table do not need to have a one-to-one relationship. In this case you are displaying blog entries, so you could have a Model named "Blog", with a method "GetList()". It is not relevant whether that query reaches out to multiple tables.
Think about it conceptually. Your are displaying blog entries, and each blog entry has other objects associated to it (such as a user id). Try to think domain-driven, not table-driven.
Make a model for the JOINS. It can include post_summary, recent_comments, etc.
Just use it in the front_page controller, the side_bar controller (for recent_comments, etc).
It would be better not to put query work directly in views or controller and views should not need to access the models IMO.

Resources