Laravel 5.4 relationship between two tables and ORM request - php

I'm making a search bar, I have a problem in the request with ORM Laravel ...
Their is my models :
class Ville extends Model
{
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function ville() {
return $this->belongsTo('App\Ville');
}
}
House table has an "id_ville". I'm searching for the request with ORM like :
public function index()
{
$search = \Request::get('search');
$houses = house::where('ville_nom', 'like', '%'.$search.'%');
return view('home')->with('houses', $houses);
}
but I can't see anything in the template ..

Check the Docs, namely the section about Defining the Inverse Relationship https://laravel.com/docs/5.4/eloquent-relationships#defining-relationships
There, you'll see this:
Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id. However, if the foreign key on the Phone model is not user_id, you may pass a custom key name as the second argument to the belongsTo method:
Since your key is prefixed with id instead of suffixed, you'll need to update your relationship to explicitly specify the FK.

If you are not strictly following the primary and foreign keys Eloquent conventions, you can easily specify your own:
class House extends Model {
public function ville() {
return $this->belongsTo(Ville::class, 'id_ville');
}
}
And here is a way to retrieve houses by searching for a Ville.
public function index(Request $request)
{
$houses = House::whereHas('ville', function ($query) {
$query->where('ville_nom', 'LIKE', '%'. $request->search .'%');
})->get();
return view('home')->with('houses', $houses);
}

Related

Laravel 6 eager loading using with() on a belongsTo relationship is only *sometimes* returning null

I am working on a project where we have a model for a service provider, the type of care provided, and the status:
Provider:
class Provider extends Model
{
protected $table = 'providers';
public function status() {
return $this->belongsTo('App\Status');
}
public function caretype() {
return $this->belongsTo('App\CareType', 'id');
}
}
CareType:
class CareType extends Model
{
protected $table = 'type_of_care';
public function providers() {
return $this->hasMany('App\Providers', 'type_of_care_id');
}
public function category() {
return $this->belongsTo('App\CareCategory');
}
}
Status:
class Status extends Model
{
protected $table = 'status';
public function providers() {
return $this->hasMany('App\Providers');
}
}
On the my SearchController (the controller that processes search requests for providers), the show() function using eager loading retrieves the caretype perfectly. But on the search() function that lists the collection of search results, the caretype is always listed as null.
I don't understand why it would be working in one function but not the other, especially when the code to eager load is exactly the same in both functions:
public function search(Request $request)
{
$validated = $request->validate([
//I removed the validation code for this post
]);
$providers = Provider::with(['status', 'caretype'])->get();
return view('search.results', ['providers' => $providers]);
}
public function show($id)
{
$single_provider = Provider::with(['status', 'caretype'])->where('id', $id)->first();
return view('search.details', ['provider' => $single_provider]);
}
Any help in this would be appreciated. I know that the model and relationship foreign keys are properly defined because the show() function is able to get the caretype just fine.
nope. your relationship and foreign keys are not correct. as from the doc
Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with a _ followed by the name of the primary key column. However, if the foreign key on the Child model is not like that, you may pass a custom key name as the second argument to the belongsTo method.
you are passing the id column as the foreign key in Provider model's caretype ralation but your foreign key is type_of_care_id. so you are getting some results when the id matches but if not, you are getting null. change your relationship code to
public function caretype()
{
return $this->belongsTo('App\CareType', 'type_of_care_id');
}
now again from the doc
If your parent model does not use id as its primary key, or you wish to join the child model to a different column, you may pass a third argument to the belongsTo method specifying your parent table's custom key.
in your case id is the primary key. so you don't have to pass the third parameter. just update the primary key reference and everything will work perfectly.

Laravel 5.2 relationship with pivot table

my tables:
every part contain many of card.
every card belong to many of part.
now,using laravel eloquent model how can fetch all card for a part without add more column to database
You need to define your relationships like below:
class Part extends Model
{
public function cards()
{
return $this->belongsToMany('App\Cards', 'user_cards');
}
}
Then you can fetch all the cards for a part like below:
$cards = Part::with('cards')->find($part_id);
Part::whereHas('cards', function($query) use ($cardId){
$query->where('id', $cardId);
})->get();
And your model relation should contain like this, for Part.php
public function cards(){
return $this->belongsToMany('App\Card');
}
And for Card.php
public function parts(){
return $this->belongsToMany('App\Part');
}

Eloquent relation with custom foreign - other key value

Is there a way to create an Eloquent relation function based on custom foreign - other key value?
For example I have level relation:
public function level(){
return $this->belongsTo(Level::class, 'level_number', 'number');
}
And I want to do something like this:
public function nextLevel(){
return $this->belongsTo(Level::class)->where('number', '=', $this->level_number + 1);
}
Is this possible or I have to write a raw query?
I had a similar situation, so I did some research in the Laravel base code and I found a very nice and clean solution.
Laravel (5.8) in BelongsTo class uses something like this finally:
$this->query->where($table.'.'.$this->ownerKey, '=', $this->child->{$this->foreignKey});
$this->child is a variable which holds Eloquent object, so we can use the magic of Eloquent getters.
The solution is creating a getter with any name and using it as a second argument, as a foreign key in relations declaration:
public function level()
{
return $this->belongsTo(Level::class);
}
public function nextLevel()
{
return $this->belongsTo(Level::class, 'next_level_id');
}
public function getNextLevelIdAttribute()
{
// any logic to get id (static value, db query etc..)
return $this->id + 1;
}

Laravel 4 querying relational relation

I've created 4 database tables:
Tool
ID | NAME | TOOLTYPE_ID
Tooltype
ID | NAME
Toolcategory
ID | NAME
Tool_Toolcategory
TOOL_ID | TOOLCATEGORY_ID
The models are as following:
class Tool extends Eloquent {
public function toolCategories()
{
return $this->belongsToMany('ToolCategory', 'tool_toolcategory', 'tool_id', 'toolcategory_id');
}
public function tooltype()
{
return $this->belongsTo('ToolType');
}
}
class ToolType extends Eloquent {
public function tools()
{
return $this->hasMany('Tool', 'tooltype_id');
}
}
class ToolCategory extends Eloquent {
public function tools()
{
return $this->belongsToMany('Tool', 'tool_toolcategory', 'tool_id', 'toolcategory_id');
}
}
Ok, my problem is getting toolcategories based on created tools with a specific tooltype.
Example I want all the categories related to the tools that has the type "Software". I am kinda lost, i have looked at trying to use scope in my toolcategory model, doing something like this:
public function scopeHasType($query, $type)
{
return $query->whereHas('tools.tooltype', function($q) use ($type)
{
$q->where('name', '=', $type);
})->exists();
}
which didn't really work :) then i tried this
$categories = ToolCategory::whereHas('tools.tooltype', function($query)
{
$query->where('tooltype_id', '=', 'Software');
})->get();
again no luck. So i was hoping that this makes sense to someone, and they could push me in the right direction. Thank you in advance.
Eloquent naming convention says:
ModelNames are StudlyCased & singular
modelMethods are camelCased (relation dynamic properties need this)
table_names are snake_cased & plural
table_columns are snake_cased
pivot_table is model1_model2 snake_cased singular (in alphabetical order)
That being said, Eloquent for a model ToolCategory looks for the table tool_categories.
So you need to specify table names whenever are not convention compliant (singular, not snake cased and so on):
// for example Tool model
protected $table = 'tool';
Also you need foreign keys to be passed to the relationship definition in order to let Eloquent know what to look for. However that you already did:
// ToolType model
public function tools()
{
// here Eloquent would look for tool_type_id (based on related model)
return $this->hasMany('Tool', 'tooltype_id');
}
// Tool model
public function tooltype()
{
// here Eloquent looks for tooltype_id by default (based on relation name)
return $this->belongsTo('ToolType');
}
Now, your relations are OK with 1 exception (keys wrong order):
class ToolCategory extends Eloquent {
public function tools()
{
return $this->belongsToMany('Tool', 'tool_toolcategory', 'toolcategory_id', 'tool_id');
}
Finally, whereHas doesn't work on nested relation (yet, check this: https://github.com/laravel/framework/pull/4954), so at the moment you need this:
// ToolCategory model
public function scopeHasType($query, $type)
{
return $query->whereHas('tools', function ($q) use ($type) {
$q->whereHas('tooltype', function($q) use ($type) {
// use table prefix, since this is going to be join
$q->where('tooltype.name', '=', $type);
});
});
}

Laravel Eloquent Joins

I have below query in core php:
SELECT DISTINCT device_tocken FROM push_details JOIN users ON users.id=push_details.user_id
I have to integrate it in laravel 4
Application already have User extends Eloquent class
I created Push_details class as below
class Push_details extends Eloquent {
public $table = 'push_details';
public function User() {
return $this->hasMany('\User','id');
}
}
Table : users
Primary key : id
Table: push_details
Primary key: id
Foreign key: user_id belongsTo('users.id');
But i m not able to get expected result.
One more thing i didn't write anything in User's model yet.
Only way to join table is.. to join it, as Eloquent relations don't work using joins but separate queries with WHERE IN clauses. So this will do:
DB::table('push_details')
->select('device_tocken')
->distinct()
->join('users','users.id','=','push_details.user_id')
->get();
Above will return array of stdObject's so or if you need Eloquent Collection with Eloquent models as a result replace DB::table('push_details')->select... with PushDetails::select...
Now, correct your relations, as they are wrong:
// PushDetails model (as previously stated, I suggest renaming it to StudlyCase)
public function user() {
return $this->belongsTo('\User','user_id'); // user_id is may be omitted here
}
// User model
public function pushDetails() {
return $this->hasMany('\PushDetails','user_id'); // user_id is may be omitted here as well
}
In your User model, you need to link back to the PushDetails model, like so
class User extends Eloquent {
public function push_details() {
return $this->belongsTo('PushDetails');
}
}
Use CamelCase for Class names, because laravel has several functions, in which CamelCase are changed to snake_case
Change
public function User() {
return $this->hasMany('\User','id');
}
to
public function users() {
return $this->hasMany('User');
}
See the docs 'Eloquent ORM' for more...

Categories