Laravel Eloquent Join 2 Tables with Different Name - php

I want to join 2 tables, t_admin and t_article using eloquent laravel. So this is table t_admin:
id_adm| name | email
-------------------------
4 | Arya | arya#mail.com
7 | Andrea | andrea#mail.com
12 | Adibah | adibah#mail.com
table t_article:
id_article | id_admin | title
--------------------------------
1 | 4 | AAA
2 | 12 | BBB
3 | 7 | CCC
based on that tables, t_admin.id_adm = t_article.id_admin.
This is my model
Admin.php
class Admin extends Model
{
protected $fillable = [
'id_adm','name','email',
];
protected $table = 't_admin';
}
Article.php
class Article extends Model
{
protected $fillable = [
'id_article','id_admin','title',
];
protected $table = 't_article';
}

Create a relationship in your Admin Model:
Note: I am assuming that an Admin can have many article.
public function articles(){
return $this->hasMany('App\Article', 'id_admin');
}
Then, whenever you want to get all articles that belong to an Admin, do this:
$adminArticles = Admin::find($adminId)->articles
In a scenario where an Admin can only have one article, do this instead:
public function article(){
return $this->hasOne('App\Article', 'id_admin');
}
Then, whenever you want to get the article that belongs to an Admin, do this:
$adminArticle = Admin::find($adminId)->article
Read here for more information.
You could also use Laravel's Query Builder to write join queries yourself.
In your case, you would do this:
$adminArticles = DB::table('t_admin')
->join('t_article', 't_admin.id_adm', '=', 't_article.id_admin')
->select('t_admin.*', 't_article.title')
->get();

Add the relationship to the models assuming its one to many
class Admin extends Model
{
protected $fillable = [
'id_adm','name','email',
];
protected $table = 't_admin';
/**
* Get the articles for admin.
*/
public function articles()
{
return $this->hasMany('App\Article');
}
}
class Article extends Model
{
protected $fillable = [
'id_article','id_admin','title',
];
protected $table = 't_article';
/**
* Get the user for the article post.
*/
public function user()
{
return $this->belongsTo('App\Admin');
}
}
You can retrieve them by
$articles = App\Admin::find(1)->articles;
foreach ($articles as $article) {
//
}

Related

Laravel union within model functions

Hello i am new here and not a native English speaker so please forgive me for any mistakes on my grammar and on my question formatting.
I am building an app with php using laravel framework 5.4 version.
The web app is very simple its for reviewing articles and users that posts articles.
I would like to learn how i can union the results of the functions within my model.
I want the allReviews function from user model to return the reviews the user has mixed with the reviews his articles have orderby createdtime.
let me explain better.
here is my 3 main tables:
Users | Articles | Reviews
--------- | --------- | ---------
id | id | id
name | user_id | reviewable_id
email | title | reviewable_type
password | body | reviewtext
etc.. | etc.. | created_time
and here is my models code :
class User extends Model{
protected $table = 'users';
public function articles()
{
return $this->hasMany(Article::class,'user_id');
}
public function reviews(){
return $this->morphMany(Review::class,'reviewable');
}
public function allReviews(){
/*
i want union something like this:
$result = $this->reviews() union
foreach ($this->Articles() as $Article) {
union $Article->reviews();
}
orderby created_time ASC or DESC doesn't matter
return $result
*/
}
}
class Article extends Model{
protected $table = 'articles';
public function user()
{
return $this->belongsTo(User::class,'user_id');
}
public function reviews(){
return $this->morphMany(Review::class,'reviewable');
}
}
class Review extends Model{
protected $table = 'reviews';
public function reviewable(){
return $this->morphTo('reviewable');
}
}
So my question is how i can do the function allReviews from user to work ?
Any help is appreciated :)
Thank You
Calling the $user->reviews property will return all reviewable models. You don't have to UNION anything, Eloquent will take care of that for you.
Try this:
public function allReviews(){
$reviews = new \Illuminate\Database\Eloquent\Collection;
foreach($this->articles as $article)
{
$reviews = $reviews->merge($article->reviews);
}
$reviews = $reviews->merge($this->reviews);
return $reviews;
}
I'm really tired now and I have a feeling you might get the N+1 query problem situation here but it should work for you.

Update a field related to the model linked by a hasOne relationship on Laravel 5.4

I have 2 tables, person and physicalperson. The person table is a general table, and the physicalperson is a specific person related to a human (because we can also have moralperson that represent a company). These two tables are linked by a OnetoOne relationship.
Table "person" :
id | name | comments | created_at
==============================================
1 Doe 2017-03-30
2 Bar Test 2017-04-05
Table "physicalperson" :
id | person_id | surname | birth
==============================================
1 1 John 1990-07-31
2 2 Foo 1970-01-01
Now I set up my relations ships, saying that for 1 person I have maximum 1 physical person :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
public $timestamps = false;
protected $table = 'person';
protected $primaryKey = 'id';
public function physical()
{
return $this->hasOne('App\PhysicalPerson');
}
}
?>
I confirm, in selection, I get all the data I need by doing a :
<?php
$person = Person::findOrFail(1);
echo $person->physical->surname; // Prints John
echo $person->name; // Prints Doe
?>
But when I try to update my person (and the associated physicalperson), I only managed to get the update for the person, and the physical seems to be ignored for an unknown reason :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
public $timestamps = false;
protected $table = 'person';
protected $primaryKey = 'id';
public function physical()
{
return $this->hasOne('App\PhysicalPerson');
}
public static function put( $id, Request $request )
{
$person = self::findOrFail( $id );
$person->name = $request->input('name');
$person->physical->surname = $request->input('surname'); // Seems to be ignored
$person->save();
}
}
Question
Does anyone already managed to updated a model "in cascade" using the Eloquent relationships methods ?
$person = self::findOrFail( $id );
$physicalPersion = physicalperson::where('persion_id' , '=' , $id)->get() ;
$person->name = $request->input('name');
$physicalPersion->surname = $request->input('surname');
$physicalPersion->save() ;
$person->save();

Relations Laravel 4 with 3 tables using Eloquent

I want to make a relation with 3 table using ORM but cant. My tables
User table
id | userame | name |
1 Ellie Elen
2 Pol Paul
record table
id | user_id| item_id| hour|
1 2 1 3
2 2 2 5
Item table table
id | title
1 item 1
2 item 2
I am using this logic but not work properly
class User Extends Eloquent {
public function record()
{
return $this->hasMany('VolunteerRecord');
}
}
class VolunteerRecord Extends Eloquent {
function item() {
return $this->hasMany('VolunteerItem');
}
}
I cant understand how to do it?
It seems like you want a Many-To-Many relationship between Users and Items but you also want to track hours on the pivot table. So first, you'll define the many-to-many relationships using belongsToMany(), and you'll tell Laravel that you have extra data on your pivot table with the withPivot() function. Your classes will look like this:
class User extends Eloquent {
protected $table = 'users';
public function items() {
return $this->belongsToMany('Item', 'records')->withPivot('hour');
}
}
class Item extends Eloquent {
protected $table = 'items';
public function users() {
return $this->belongsToMany('User', 'records')->withPivot('hour');
}
}
Then, to access the hour field you would do this:
$user = User::first(); // First User
$item = $user->items()->first(); // User's first Item
$hour = $item->pivot->hour; // The 'hour' on the User-Item relationship
Also, your current column naming scheme is correct for Laravel so don't feel like you need to change it. If you change your column names, then you'll need to define them in the belongsToMany() method like this:
$this->belongsToMany('ModelName', 'pivot_table', 'foreign_key', 'other_key');
// For example, in Items::users() you would have this:
$this->belongsToMany('User', 'records', 'users_id', 'items_id');
Finally, I'm assuming that your tables are named users, items, and records. If they are not, then just replace all instances of users, items, and records with your actual table names.
Based on your table names, I'd suggest the following, first of all, change your record table as follows:
id | users_id| items_id| hour|
1 2 1 3
2 2 2 5
And these are the classes for your models:
class Users extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
public function records()
{
return $this->hasMany('Records');
}
}
class Records extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'records';
public function record()
{
return $this->hasOne('Users');
}
public function item()
{
return $this->hasOne('Items');
}
}
class Items extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'items';
public function records()
{
return $this->hasMany('Records');
}
}
These contain the relations for your models.
If you were to select a few records, for each record you can get the user and the item. If you were to select an item, and all records for that item. You can also get the user for each record.
In User Model
public function images()
{
return $this->belongsToMany('Item')->withPivot('hour');
}
In user controller
public function view($username)
{
$user = User::where('name',$username)->firstOrFail();
return View::make('view')->with('user',$user);
}
In view
#foreach ($users->items as $item)
name: {{$image->title}}<br>
hour: {{$image->pivot->hour}}<br>
#endforeach

Many to Many relationship query. Laravel

I'm trying to figure out how I can do a query within a query. (if that even makes sense) I want to grab all the activities. For each activity I want to get the count of users that did the activity. Then I want to order all the activities in DESC order based on the amount of users that did each activity. I'm basically making a "Popular Activities Page" where I show the all activities starting with the activity done by the most users.
I have 3 main tables for this
users
| id | name | password | email | created_at |
activities
| id | title | description | created_at |
resource This is a table I'm using for posts which shows which user did which activity. (Users can show what activities they did, and attach media and locations to the post)
| id | user_id | activity_id | media_id | location_id | created_at |
Here are my models for each table
User Model
class User extends Eloquent {
protected $table = 'users';
/**
* get the activities associated with the given user
* #return mixed
*/
public function activities()
{
return $this->belongsToMany('Acme\Activities\Activity', 'resource', 'activity_id');
}
public function posts(){
return $this->hasMany('Acme\Resource\Resource');
}
public function media()
{
return $this->hasMany('Acme\Media\Media');
}
public function locations()
{
return $this->hasMany('Acme\Locations\Location');
}
}
Activity Model
class Activity extends Eloquent {
protected $table = 'activities';
public function posts(){
return $this->hasMany('Acme\Resource\Resource', 'resource_id');
}
/**
* get the users associated with the given activity card
* #return mixed
*/
public function users()
{
return $this->belongsToMany('Acme\Users\User', 'resource', 'user_id');
}
}
Resource Model
class Resource extends Eloquent {
protected $table = 'resource';
public function user()
{
return $this->belongsTo('Acme\Users\User', 'user_id');
}
public function activities()
{
return $this->belongsTo('Acme\Activities\Activity', 'activity_id');
}
public function media()
{
return $this->hasMany('Acme\Media\Media', 'media_id');
}
public function locations()
{
return $this->belongsTo('Acme\Locations\Location', 'location_id');
}
}
I know I can get all activities using
Activity::get()
I can get a user count for a specific activity using
User::whereHas('resource', function($q) use ($activity_id){
$q->where('activity_id', $activity_id);
})->get()->count();
but I don't know how I can put all of this together in order to get all Activities sorted by user count, starting with the activity with the highest user count.
How would I make this query using eloquent?
Thanks in advance!
try
Resource::select(DB::raw('*, COUNT(distinct(user_id)) as user_count'))->group_by('activity_id')->order_by('user_count', 'desc')->get();
You could then do this
$results = Resource::select(DB::raw('*, COUNT(distinct(user_id)) as user_count'))->group_by('activity_id')->order_by('user_count', 'desc')->get();
foreach ($results as $result) {
$activity = Activity::where('id','=',$result->activity_id)->first();
// do stuff to display data for this activity like
// $activity->title or $activity->description
$count = $result->user_count;
}

Laravel Cities relation foreign key

Im really new to laravel, and im sure im doing something wrong
I have 2 tables. Cities And users_metadata
My cities table look like this
id | City |
1 | New York |
1 | Los Angeles |
users metadata
user_id | firt name | last name | cities_id |
1 | Jonh | Doe | 2 |
So my problem is when i create a relation i get New York, becaus the city id is matched with the user id
City model
class City extends Eloquent
{
public static $table = "cities";
public function profile()
{
return static::has_many('Profile');
}
}
profile model
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public static $key = "user_id";
public function city()
{
return static::has_one('City');
}
}
error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'profile_id' in 'where clause'
SQL: SELECT * FROM `cities` WHERE `profile_id` = ? LIMIT 1
Bindings: array (
0 => 1,
)
If i dont pass the id to has one i get the following error
Okay i understand this.
So my questions is am i able to pass the foreign key cities_id somehow in my relation to match? Or im doing it all wrong? Can someone give me a basic example?
thank you folks
Try this:
City model
class City extends Eloquent
{
public static $table = "cities";
public function profile()
}
Profile model
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public static $key = "user_id";
public function city()
{
return static::belongs_to('City');
}
}
I ran into the same problem thinking I should use has_one, but I needed to use belongs_to. user1808639's probably didn't work because you still had a 'has_many' in the city model.
Try this:
class Profile extends Eloquent
{
public function city()
{
return $this->belongs_to('City'); // city_id in the table
}
}
Laravel has a way of detecting foreign keys automatically. So for your database schema... this models should work fine
Try the following
user_id | firt name | last name | city_id | //city not cities
1 | Jonh | Doe | 2 |
-
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public function city()
{
return $this->has_one('City');
}
}
/
class City extends Eloquent
{
public static $timestamps = false;
public function profiles()
{
return $this->has_many('Profile');
}
}
The table rows shouldn't contain whitespaces. So rename "firt name" | "last name" in "firstname" | "lastname". The SQL-error shows me that you're calling the model in the reverse way like City::find(1) in this case Laravel expects inside the "Cities" table the foreign key for the profiles that would be usually "profile_id".
I guess you're looking for something like this:
$user_id = 1;
$user = Profile::find($user_id);
echo $user->firstname." ".$user->lastname." lives in ".$user->city->city;

Categories