Join multiple tables Eloquent - mysql

Laravel version 4.2
I am trying to Join multiple tables and get results
I have now 2 tables
1- projects_info (id - pro_title - pro_address ...)
2- projects_images (id - image - image_id)
I need to grape the related images from the 'projects_images' where image_id = projects_info id
here what I try
here is my Route
//Projects Route
Route::get('our-projects', 'projectController#currentProjects');
Route::get('project/{id}', 'projectController#viewProject');
//Projects details
//Route::get('project/{id}/about-project', 'projectController#viewProject');
Route::get('project/{id}/about-project', array('as' => 'about-project', 'uses' => 'projectController#viewProject'));
Route::get('project/{id}/project-images', array('as' => 'project-images', 'uses' => 'projectController#viewProjectImages'));
Projects Model
class Projects extends Eloquent implements UserInterface, RemindableInterface
{
use UserTrait, RemindableTrait;
protected $table = 'project_info_arabic';
public function projectImages()
{
return $this->belongsTo('ProjectsImages', 'image_id');
}
}
ProjectsImages Model
class ProjectsImages extends Eloquent implements UserInterface, RemindableInterface
{
use UserTrait, RemindableTrait;
protected $table = 'projects_images';
public function project()
{
return $this->hasOne('Projects', 'id');
}
}
and this is my ProjectController
public function currentProjects()
{
$pro = Projects::all();
return View::make('projects.currentProjects', ['pro' => $pro]);
}
public function viewProject($id)
{
$vp = Projects::find($id);
return View::make('projects.viewProject', ['viewPro' => $vp]);
}
public function viewProjectImages($id)
{
$vpi = ProjectsImages::with('project')->get();
//$vpi = DB::table('projects_images')->select('id', 'image', 'image_id')->get();
return View::make('projects.projectDetails.projectImages', ['viewProImg' => $vpi]);
}
and here is how I am trying to include each page in my projectsDetails VIEW
<div class="mCustomScrollbar">
#if(Request::path()=="project/$viewPro->id/about-project")
#include('projects.projectDetails.aboutProject')
#elseif(Request::path()=="project/$viewPro->id")
#include('projects.projectDetails.aboutProject')
#elseif(Request::path()=="project/$viewPro->id/project-images")
#include('projects.projectDetails.projectImages')
#endif
</div>
and last the projectImages VIEW
<ul>
#foreach($viewProImg as $vpi)
<li class="col-sm-3 col-xs-12">
{{ HTML::image("images/projects/$vpi->image", '', array('class'=>'img-responsive')) }}
</li>
#endforeach
</ul>
My Problem
1- what I got here is all the images in the table it should be only the images related to this project
any help here please

First of all, the project has many images
public function projectImages()
{
return $this->hasMany('App\ProjectsImage');
}
.. and the image belongs to a project
public function project()
{
return $this->belongsTo('App\Project', 'project_id');
}
You should always refer to the model. If you are referring to a model then you should have in mind that its good practice to name the models in singular form, as in Project and ProjectImage. In Laravel, they expect you to have name the tables name in plural and the model name in singular. So if you haven't explicit set the table name, it will look for the model name plus a s (ProjectS).
Then, you can call the projectImages -function from a Project object. So in the view it will look something like this
#foreach($project->projectImages()->get() as $image)
// Do what you want with each project images
#endforeach

Related

Laravel: Select from Database

in my Laravel App I have two tables:
Projects
- id
- user_id
- name
- etc...
Images
- id
- project_id
- url
How can I achieve it, to show all the Projects each user has and all the connected images (each project can have up to 20 images (stored in FTP) and Link in Field URL - the project_id from table "Projects" will be saved in field images.project_id)?
I learned, that I can show the projects like this:
$projects = DB::table('projects')->where('user_id','=',$user->id)->get();
and I tried with
$images = DB::table('images')->where('project_id','=',$projects->id)->get();
But I get an error message:
Property [id] does not exist on this collection instance.
What I am missing? Thank you for pointing me into the correct direction :-)
Kind Regards,
Stefan
For your question i suggest to use eloquent way like set up your models
class Project extends Model
{
public function images()
{
return $this->hasMany(\App\Models\Image::class, 'project_id');
}
public function user()
{
return $this->belongsTo(\App\Models\User::class, 'user_id');
}
}
class Image extends Model
{
public function project()
{
return $this->belongsTo(\App\Models\Project::class, 'project_id');
}
}
Now to find projects with their images you can query as
$projects = Project::with('images')->get();
Each object in $projects will have collection of their associated images.
To add filter for user you can use whereHas on relations
$projects = Project::with('images')
->whereHas('user', function ($query) use ($user) {
$query->where('id', '=', $user->id);
})->get();

Joining Two Tables to a Reference Table Laravel

I Have three tables
#1 Table timeline which is my reference table with an Auto incremented ID which is stored in column id
#2 timeline_videos
#3 timeline_else
What happens is on post if a video is uploaded with the post
it will go into Table #2 ,anything else goes into Table #3.
#2-3 have the Auto Increment Id from the Table timeline stored in a column pid
On query of The Timeline I need to join both tables data using id=pid
so I can use the rest of the Relational Data with the post.
I have done a bit of research and can't seem to find a method for doing so.
So far the code I have
Controller
$groupposts = timeline::where([
['owner','=',$owner],['id','<',$lastid],
])
->join('timeline_videos','timeline.id','=','timeline_videos.pid')
//->join('timeline_else','timeline.id','=','timeline_else.pid')
->orderBy('id','desc')
->limit(5)
->get();
This works with no errors with the second Join commented out but I need to also grab the timeline_else data .
Update --
I have now decided to use Eloquent Relationships to join the tables,
my question now is what type of relationship do I have between the
tables?
I realize it basically needs to be able to switch between two tables to
grab data based on the fact that timeline_videos and timeline_else will not be "JOIN" but separated by type .
The tables need to Join with table #1 timeline based on a column I now have named type for clarifying where to look and matching/joining using the id = pid
You can use relationships.
it sounds like timelines has many videos and has many video failures
https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
you would have a model for each table and set up the relationships
timelines model:
public function videos()
{
return $this-> hasMany('App\Videos');
}
public function videoFailures()
{
return $this-> hasMany('App\videoFailures');
}
videos model:
public function timeline()
{
return $this->belongsTo('App\Timelines');
}
videos failures model:
public function timeline()
{
return $this->belongsTo('App\Timelines');
}
You can then go:
$timeLine = Timmeline::find($id);
to find videos of the time lines you would do:
$videos = $timeLine->videos();
to find else:
$videoElse = $timeLine-> videoFailures();
By using some of what Parker Dell supplied and a bit more trial and error
My Models Looks like
timeline
class timeline extends Model
{
protected $table ='timeline';
public $timestamps = false;
public function videos()
{
return $this->hasMany('App\timeline_videos','pid','id');
}
public function else()
{
return $this->hasMany('App\timeline_ect','pid','id');
}
}
timeline_ect.php ,I changed the name of the table
class timeline_ect extends Model
{
protected $table='timeline_ect';
public $timestamps = false;
public function timeline()
{
return $this->belongsTo('App\Models\timeline','pid','id');
}
}
timeline_videos
class timeline_videos extends Model
{
protected $table='timeline_videos';
public $timestamps = false;
public function timeline()
{
return $this->belongsTo('App\timeline','id','pid');
}
}
Then Lastly my Controller
$timeline = timeline::with('videos','else')
->orderBy('id','desc')
->limit(5)
->get();
So far no Problem query is correct.

Yii2 Restful. How can i receive data from 3 tables

I want to receive data like this:
categories
----category1
----category2
topProducts
----product1
--------photo1
--------photo2
----product2
--------photo1
--------photo2
I need get all categories and top x products.
Each product has two photos.
How can i do this by using yii2 restful?
Thanks.
the query shold look something like this
Category::find()
->with(['subcategories','topProducts', 'topProducts.images'])
->all();
you can use joinWith if you absolutely want a single query
if you retrieve your data with an ActiveController, you need to specify extraFields to the Category model. (here's a rest-specific usage example - rest of the guide should prove usefull as well)
Category model:
public function extraFields() {
return ['subcategories', 'topProducts'];
}
// product relation
public function getTopProducts(){
return $this->hasMany(Product::className(), ['category_id' => 'id'])
// ->order()->where() // your criterias
->limit(10);
}
// subcategories
public function getChildren(){
return $this->hasMany(Category::className(), ['id' => 'parent_id']);
}
Product model:
public function extraFields() {
return ['iamges'];
}
public function getImages(){
return $this->hasMany(Image::className(), ['product_id' => 'id'])
}
ps. since you haven't posed any code or table structure, all relations in my example are based on standard naiming convention

How to view data using junction table Yii2

I've got three tables
checkoutcounter {id, name}
user {id, username}
checkoutcounter_users { id, checkoutcounter_id, user_id}
I use gii and then add
in checkoutcounter model (I add and joinWith and find()->with but it still doesn't work):
public function getUser_display()
{
return $this->hasMany(User_display::className(), ['id' => 'user_id'])
->viaTable(CheckoutcounterUsers::tableName(), ['checkoutcounter_id' => 'id']
);
}
In checkoutcounter model search:
public function search($params)
{
$query = FinanceSettingsCheckoutcounter::find()->with('user_display');
$query->joinWith('user_display');
}
what should I add in checkoutcounter view to get usernames or user id's? Why when I add in gridview 'attribute'=>'user_display.id' it doesn't display any data?
echo yii\helpers\Json::encode($dataProvidercheckoutcounter);
shows
{"query":{"sql":null,"on":null,"joinWith":[[["user_display"],true,"LEFT JOIN"]],"select":null,"selectOption":null,"distinct":null,"from":null,"groupBy":null,"join":null,"having":null,"union":null,"params":[],"where":null,"limit":null,"offset":null,"orderBy":null,"indexBy":null,"modelClass":"app\\models\\FinanceSettingsCheckoutcounter","with":["user_display"],"asArray":null,"multiple":null,"primaryModel":null,"link":null,"via":null,"inverseOf":null},"key":null,"db":null,"id":null}
Im not sure how you're using your search() function, but you're not using $params.. And its not returning the results..
I belive the query should be like this:
public function search($params)
{
$result = FinanceSettingsCheckoutcounter::find()->with('user_display')->all();
echo yii\helpers\Json::encode($result);
}
if you are using this as part of a Search Model, returning a dataProvider, check out this link
http://www.ramirezcobos.com/2014/04/16/displaying-sorting-and-filtering-model-relations-on-a-gridview-yii2/

Why is my find clause not working?

I have three models: Company, Office, CompanyPersonTask. The Company model has many Office and has many CompanyPersonTask.
So, why is this code:
public function getCompaniesByRegion($region){
$options['conditions'] = array("UPPER(Office.region) LIKE UPPER('".$region."%')");
return $this->find('all', $options);
}
resulting in the following error ?
"Unknown column 'Office.region' in 'where clause'"
The region column is present in the offices table.
As if you have specified the proper association-ship between Company with Office and CompanyPersonTask. i.e. Company hasMany Office and Company hasMany CompanyPersonTask.
Then you could write it as:
In your Company Model write:
public $actAs = array('Containable');
Your method should be:
class AppController extends Controller
{
public $uses = array('Company', 'Office', 'CompanyPersonTask');
protected function _getCompaniesByRegion($region){
return $this->Company->find('all', array('contain' =>
array('Office' => array('conditions' => array("UPPER(Office.region) LIKE " => "UPPER('".$region."%')")))
)
);
}
}
You can call this method into any controller using $this->_getCompaniesByRegion($region_val);