I am making a social network using Codeigniter and I'm trying to make the users view show a button when you are already following a person how do I do that??
Model
<?php
class User_model extends CI_Model {
function get_All(){
$this->db->select('*');
$this->db->from('membership');
// $this->db->join('following', 'following.id = membership.id');
$q = $this->db->get();
if($q->num_rows() > 0) {
foreach ($q->result() as $rows) {
$data[] = $rows;
}
return $data;
}
}
It's a little bit of work. Assuming that all users can be searched, you might have a list of all users, and of the 'friends' of all users. Then you run through the two comparing them. The following is an idea:
Database Members: All members |ID_User|...other user stuff...
Database Followers: Lists all friendship |ID_User|ID_Follower|
You need two queries for this: One for all, and one for Followers where ID_User=$UserID. As you run through all members as you suggest, then you can
function get_Followers(){
$friends= $this->db->query('SELECT * FROM Followers WHERE ID_User=$UserID');
$follow_array=$row->ID_Follower;
}
Now:
$follow_array //A list of all friends.
$q //Your original list of members
Then you can use:
if($q->num_rows() > 0) {
foreach ($q->result() as $rows) {
if(in_array($rows->ID_Follower, $Follower_array))
{
$data=true;
}
else
{
$data=false;
}
}
return $data;
}
Beware however, this may be a very server-heavy operation.
I'm going to assume you're talking about visiting a persons profile and if you are following that person you see a button. That only requires one query and logic in the view itself.
Going on this assumption you're already passing the person who's profile you're viewing to the view so all you need is a list of people the viewer is following to compare that id to.
I'm not really sure what your query in your code is doing since there's no description of your database so I'll give the code the way the tables should be laid out, which is a user table and a following table that is just a join table on the users. Assuming the following table has 3 columns id, userId, followingId where userId is you and followingId is the person you are following.
Controller
$data['following'] = $this->modelName->getFollowing($userId); //pass current userId
$this->load->view('viewName',$data);
Model:
public function getFollowing($userId)//$userId to be passed as the person viewing.
{
$this->db->where('userId',$userId);
$data = $this->db->get('following');
if($this->db->num_rows() > 0)
{
return $data;
} else {
$data=array();
$return $data;
}
Then in the view it's a simple if statement.
if(in_array($profileId,$following))
{
echo button;
}
Related
First post here, hope all is well with everyone! I am working on my senior project and struggling with this concept. Maybe it isn't possible, or it is and I'm thinking about it the wrong way.
I currently have this- This displays the student, with all its foreign keys in the other tables. In settings, there is a foreign key 'conversion_id.', I would like settings on the student call(code below) to ALSO display the conversion table, from the FK in settings.
$student = Student::with('studentIntroSurveys', 'settings', 'giftsSurveyResults',
'studentGiftSurveys', 'devotionals', )->get();
If this does not make sense, I am sorry. I am still l new to the language.
(Code to display students. It shows settings, but not the conversions within settings.)
$student = Student::with('studentIntroSurveys', 'settings', 'giftsSurveyResults',
'studentGiftSurveys', 'devotionals', )->get();
if (!$student) {
return response('No Data', 400);
} else {
return response($student);
}
I would like it to display this settings, but WITH the conversion_id table!!
What it displays =
settings: { setting_id: 4, student_id: 1, dark_mode: 1, conversion_id: 1,
notification_enabled: 1, notification_time: "08:00:00" } `
my has-one method =
public function settings()
{
$settings = $this->hasOne(Settings::class, 'student_id', 'student_id');
return $settings;
}
You can use the dot syntax for nested eager loading: 'settings.conversation' e.g.
$student = Student::with('studentIntroSurveys', 'settings.conversation', 'giftsSurveyResults', 'studentGiftSurveys', 'devotionals', )->get();
Alternatively, you could set up a belongsToMany relationship on the Student model and use settings as the pivot table:
public function conversations()
{
return $this->belongsToMany(Conversation::class, 'settings')
}
Just a few FYIs:
Your if statement is never going to return the 400 response as $student is always going to be a collection. You could instead do if ($student->isEmpty()).
I would also recommend changing the variable to $students as it will be a collection of students rather than a single student.
You can simple your settings relationship by removing the temporary variable and just returning the relationship:
public function settings()
{
return $this->hasOne(Settings::class, 'student_id', 'student_id');
}
for my app I made it so an user can favorite venues, this relationship between venues and user is many to many, problem is I don't know how to get favorite_venues paginated.
Right now what I'm doing is getting user with favorite_venues but that doesn't seem right to me, is there a way to get favorite venues paginated directly without having to get the user.
What I'm currently doing:
public function getFavorites($request)
{
$user = User::with(['favoritevenues','favoritevenues.category'])->findOrFail(1);
return $user;;
}
I set relationships like this:
User Model
public function favoritevenues()
{
return $this->belongsToMany('App\Models\Venue', 'favorite_venues', 'user_id', 'venue_id')->withTimeStamps();
}
Venue Model
public function favorites()
{
return $this->belongsToMany('App\Models\User', 'favorites', 'venue_id', 'user_id')->withTimeStamps();
}
Thanks in advance
you can do:
Venue::whereHas('favorites', function ($q) {
return $q->where('id', 1);
})->paginate(5);
This will get and paginate all the venues which are the favourites of user with id 1
The title of the question may seem weird, but I'll explain it briefly. I'm not experiencing any issues yet, but considering any advice regarding the following approach.
I have the following tables:
articles
hasMany(tags)
movies
hasMany(tags)
series
hasMany(tags)
subs (morph)
media_id
media_type
user_id
All of the first three tables have many tags, where the subs table have a Morph relation between them all.
The concept is simple, the user can subscribe to movies and/or series and NOT articles, let's say, opt-in a record from movies.
The following record will be inserting:
media_id => 1, media_type => movie, user_id => 1
Let's say we have 10K records like this in subs table. Now, I create a record in articles with specific tags. I want to notify all users in subs, who are opted-in movies and/or series that have exactly the same tags as the record I'm targeting from articles.
TL;DR: Notifying users that are interested in specific tags from movies or series.
To achieve this, I added the morphTo in the subs model:
public function media(){
return $this->morphTo();
}
The logic is straightforward:
Get the article.
Get the tags() relationship and save it into a variable.
Check if tags are not empty, if not, continue
Get all the subs.
Get the morphTo relationship and get its tags.
Compare and continue.
$article = MediaArticle::find($notificationable_id);
$article_tags = $article->tags;
$subbed_users = array();
if (empty($article_tags) === false) {
$subs = NotificationMediaSub::all();
foreach ($subs as $sub) {
$sub_tags = $sub->media->tags;
foreach ($sub_tags as $sub_tag) {
foreach ($article_tags as $article_tag_title) {
if (strcasecmp($sub_tag->title, $article_tag_title->title) === 0) {
array_push($subbed_users, $sub->user_id);
}
}
}
}
// continue here
}
I find this approach really intensive and may cause the server to slow down a lot. Is there a better approach to achieve my goal?
=========================
Approach
I defined the media_tags_relationship as a Model, inside it:
public function media() {
if ($this->taggable_type === AdminHelper::MORPH_MEDIA_TRANSLATION_MOVIE['original']) {
return $this->belongsTo(MediaMovie::class, 'taggable_id', 'id');
} elseif ($this->taggable_type === AdminHelper::MORPH_MEDIA_TRANSLATION_SERIES['original']) {
return $this->belongsTo(MediaSeries::class, 'taggable_id', 'id');
}
return $this->belongsTo(MediaMovie::class, 'taggable_id', 'id')->where('id', 0);
}
Now, I'm fetching the subs like this:
$article = MediaArticle::find($notificationable_id);
$article_tags = $article->tags;
$subbed_users_tokens = array();
if (empty($article_tags) === false) {
$article_tags = $article_tags->map(function ($tag) {
return $tag->title;
});
$related_tags = MediaTag::whereIn("title", $article_tags)->get();
$related_tags = $related_tags->map(function ($tag) {
return $tag->id;
});
$tags_relationship = MediaTagsRelationship::whereIn("tag_id", $related_tags)->where("taggable_type", "movie")->orWhere("taggable_type", "series")->get();
foreach ($tags_relationship as $tag_relationship) {
$media = $tag_relationship->media()->with('subs')->get();
if (empty($media) === false) {
$media = $media[0];
$subs = $media->subs->map(function ($sub) {
return $sub->firebase_token;
});
array_push($subbed_users_tokens, $subs);
}
}
}
I have a model Shop and a model Comment.
on the Comment model:
public function shop()
{
return $this->belongsTo('App\Shop', 'commentable_id');
}
The Shop model is:
public function comments() {
return $this->hasMany('App\Comment', 'commentable_id');
}
So the relationship is One To Many
I want to copy all the comments of a Shop and attach them to another Shop:
$shop = Shop::find(1);
$comments = $shop->comments()->pluck('id')->toArray(); // it works, i have all the ids of the comments
$othershop = Shop::find(2);
$othershop->comments()->associate($comments); // doesn't work
$othershop->comments()->attach($comments); // doesn't work
Anyone knows how to proceed with a One to Many situation?
You can utilize createMany method of relationship:
$othershop->comments()->createMany($shop->comments->toArray());
You can also utilize chunking if one shop can have many comments (split it into more queries to make it more memory efficient):
$shop->comments()->chunk(500, function ($comments) use ($othershop) {
$othershop->comments()->createMany($comments->toArray());
});
edit: changed my answer based on comments.
To copy comments, you first need to replicate them. Then you can associate them with their owning model:
$shop = Shop::find(1);
$otherShop = Shop::find(2);
$comments = $shop->comments()->get();
foreach ($comments as $comment) {
$tmp = $comment->replicate();
$tmp->shop()->associate($otherShop);
$tmp->save();
}
How to check whether there's data from database or not
My DB looks like this
My user Model
public function monsters()
{
return $this->belongsToMany('App\Monster')->orderBy('star');
}
My Controller
public function list_monster_user()
{
//GET USER LOGIN ID
$id = Auth::user()->id;
$monster_user = User::find($id);
//IF DATA IS NOT EMPTY OR USER HAVE MONSTERS
if(!is_null($monster_user->monsters))
{
return 'yes';
}
//IF DATA IS EMPTY OR USER DOESNT HAVE ANY MONSTER
else
{
return 'nope';
}
}
I'm using ajax, so the result will be return to ajax.
I don't get the return I want. I know something's wrong with my if statement.
But I couldn't figure it out.
Since you are not following naming conventions, you should specify all fields in belongsToMany function. Try this:
return $this->belongsToMany('App\Monster', 'karakter_has_monster', 'karakter_id', 'monster_id');
And to check for results, you could use count(). It would be faster.
if($monster_user->monsters()->count() > 0) {
//has monsters
}