I keep multiple address records belonging to a user. but when i write with dd i can't access other table's data.
Following my code:
user Table
id | name | country |
--- -------------- ----------
7 | Mr. Lenny Bins| Belgium
2 | Dalton Miller | Swaziland
address Table
user_id | address
-------- ---------
7 | 740 Brown Greens Suite
7 | 9906 Cleora Wall Apt.
2 | 53977 Kip Center Apt
UserModel
public function getAddress()
{
return $this->hasMany(Address::class);
}
UserController
$users = User::where('id' ,7)->with('getAddress')->get();
dd($users->toArray());
// The output of this is below
dd($users->getAddress->toArray());
I get an error when I try like this.
Property [getAddress] does not exist on this collection instance.
Firstly you are using get that will return collection, In Following you will get all users with their addresses.
$users = User::where('id' ,7)->with('getAddress')->get();
You can use first() instead of get() as you are finding only one user
$user = User::where('id' ,7)->with('getAddress')->first();
If You want only address of that user use
dd($user->getAddress)
Or If you want only in form of array use
dd($user->getAddress->toArray())
User Model
public function getAddress()
{
return $this->hasMany('App\Address');
}
Get User(s)
$users = \App\User::with('getAddress')->where('id' ,7)->get();
Iterate and read data
foreach ($users as $user) {
echo '<pre>' , var_dump($user->getAddress()->first()['address']) , '</pre>';
}
$users = User::with('getAddress')->where('id' ,7)->first();
dd($users);
Related
I have a database with multiple address records of a user. When I do "pluck()" and "join()" in the foreach path, I get results. But when I type $user->getAddress->address in structures like hasOne, I get the result I want. In short, can I return the loop in hasMany more practically?
Following my code:
user Table
id | name | lastname |
--- -------------- ----------
1 | Rahuel | lastnameRahuel
2 | Dalton Miller | lastnameDalton
adress Table
user_id | address
-------- ---------
1 | 740 Brown Greens Suite
1 | 9906 Cleora Wall Apt.
2 | 53977 Kip Center Apt
UserModel
public function getAddress()
{
return $this->hasMany(Address::class);
}
Controller
$users = User::with('getAddress')->get();
foreach ($users as $user){
echo $user->name;
echo $user->lastname;
echo $user->getAdress->pluck('address')->join(',');
}
You can use the Collection 's implode method to make it look a bit less verbose.
echo $user->getAdress->implode('address', ',');
Consider a table of nested locations which has columns for the location_id, its name and a parent_id. This parent field lets you know that you're in a nested location.
Example setup:
Locations
-----------------------------------
location_id | name | parent_id
-----------------------------------
1 | Isle A | NULL
2 | Column 23 | 1
3 | Shelf 2 | 2
4 | Box C | 3
Let's say we have an item sitting in location_id=4.
We now want to easily show the item's full location in a comma separated format. We expect to see:
Isle A, Column 23, Shelf 2, Box C
In order to achieve that, I have the following Laravel Model with a full_name() function which takes care of formatting and recursive calls:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Location extends Model
{
protected $table = 'locations';
protected $primaryKey = 'location_id';
protected $with = [
'location'
];
public function location()
{
return $this->hasMany('App\Location', 'parent_id', 'location_id');
}
public function full_name()
{
return ($this->location ? $this->location->full_name() . ', ' : '') . $this->name;
}
}
Nothing fancy soo far, works correctly and outputs what I need it to.
Now imagine down the line, some other piece of code allows for a mistake and the following happens:
Locations
-----------------------------------
location_id | name | parent_id
-----------------------------------
1 | Isle A | NULL
2 | Column 23 | 3
3 | Shelf 2 | 2
4 | Box C | 3
Notice that location #2's parent_id changed to 3. This creates an infinite loop of joins between 2 and 3. Laravel will not detect this recurrence (after all we're telling it to keep joining) and the execution will eventually die. This is my problem.
A possible solution I thought about would be to keep an ongoing list of "visited" location_id's, and if we stumble upon a repeat, we terminate the execution. If this was a "normal" function, I recon something like this would work:
public function location($recurrence_guard = [])
{
if(in_array($this->location_id, $recurrence_guard)) {
return collect([]); // or null?
}
array_push($recurrence_guard, $this->location_id);
return $this->hasOne('\App\Location(<somehow pass $recurrence_guard_in_here>)', 'location_id', 'parent_id');
}
Clearly this is nonsense and that's not how Laravel's relationships work. I'm looking for ideas on how to pass extra parameters into the relationships or for any better ideas on how to design this.
Thanks!
I want to try to display messages according to their conversation ID. The rules are a conversation hasMany messages and a message belongsTo only one conversation.
What I've tried
I have this in my controller :
public function index()
{
$from = Input::get('from',null); //timestamp of latest message
$conv_id = Input::get('conv_id'); //get an array of conversation ids
$allmessages = Conversations::whereIn('id',$conv_id)->with('messages');
if(is_null($from)){
$messages = $allmessages->orderBy('created_at','desc')->take(10);
}else{
$messages = $allmessages->where('created_at','>',$from);
}
return $messages->get()->reverse();
}
but I got the error message,
"SQLSTATE[42S22]:Column not found: 1054 Unknown column 'messages.conversations_id' in
'where clause'(SQL: select * from `messages` where `messages`.`conversations_id` in (1, 2))",
I can't seem to figure out where I've gone wrong. Improvement of code will be a bonus. Thank you!
I have two models, Conversations and Messages. These are the tables. I intentionally left out the timestamp columns of both tables for this question's purpose.
Conversations
+---------+----------+
| id | name |
+---------+----------+
| 1 | haha |
| 2 | hehe |
+---------+----------+
Messages
+---------+----------+-----------------+
| user_id | conv_id |body |
+---------+----------+-----------------+
| 1 | 1 |user1 says hi! |
| 2 | 1 |user2 says seen! |
+---------+----------+-----------------+
Here is the function linking those two models.
Conversation model
public function messages(){
return $this->hasMany('Messages');
}
Messages model
public function conversations(){
return $this->belongsTo('Conversations');
}
Your error message says
messages.conversations_id
But your table schema is listed as
conv_id
So it seems you are using the wrong id field somewhere (I cant tell where as you have not posted enough code - but you should be able to find it. If not - post more code from your model).
Try changing the relation in your Messages model to:
public function conversations() {
return $this->belongsTo('Conversations', 'conv_id');
}
The second parameter specifies the column to use as the foreign key: by default it would be 'conversations_id' (based on the model name).
can anybody help me on the following query.
I have a table that holds a postcode column and a rating column, ie.
ID | POSTCODE | RATING
1 | sk101dd | E
2 | sk101de | A
3 | sk101df | E
4 | sk101dg | E
5 | sk101dh | D
etc
This is set up as a model called PostcodeList
I have a relational table, linked via the RATING column that holds a customer id and cost, ie.
ID | CUSTOMER_ID | RATING | COST
1 | 1234 | E | 0.05
2 | 9999 | E | 0.02
This is set up as a model called RatingCost. I linked this to PostcodeList model using the following code:
public function costing()
{
return $this->hasMany('PostcodeList','RATING','RATING');
}
I need to return the COST from the RatingCost model using CUSTOMER_ID as the filter without resorting to multiple sql statements. I think I've nearly got it, using the code below, but it's not quite right:
$p = PostcodeList::where('postcode',$somepostcode)->first();
$cost = $p->costing()->where('customer_id',$somecustomerid)->first()->cost;
The error I'm getting at the moment is "Trying to get property of non-object".
Any help greatly appreciated. I don't want to resort to DBRAW or another form of join as I really like the relational setup Laravel provides.
thanks
I know you're trying to stay away from joins, but this Laravel query would produce the desired results:
DB::table('PostcodeList')
->join('RatingCost', function($join)
{
$join->on('RATING', '=', 'RatingCost.RATING')
->->where('customer_id',$somecustomerid)
})
You have this
$postcode_get = PostcodeList::where('postcode',$somepostcode)->get();
foreach($postcode_get as $p){
...
$cost = $p->costing()->where('customer_id',$somecustomerid)
// ...
}
You have defined the method costing in your RatingCost model but calling it from PostcodeList model, in this case you need to declare the relation inside your PostcodeList model like this:
public function costing()
{
// change the field name 'RATING' in any table, maybe
// prefix with table name or something else, keep different
return $this->belongsToMany('RatingCost','RATING', 'RATING');
}
So, you can use this (inside loop):
$cost = $p->costing();
Because, inside your loop each $p represents a PostcodeList model and $postcode_get is a collection of PostcodeList models.
I don't think what I'm trying to do is actually possible without using joins. So the solution was to scrap the belongsTo and hasMany options for a standard join (similar to dev_feed's response):
$pr = PostcodeList::join('RatingCost', function($join)
{
$join->on('PostcodeList.content_rate', '=', 'RatingCost.code');
})
->where('postcode', '=', $somepostcode)
->where('RatingCost.customer_id','=',$somecustomerid)
->first();
I am new to eloquent for laravel 4 and i can't quite figure out on how to make and save related models.
Table Messages: id | user | message | parent
For example:
class Message extends Eloquent {
public function user(){
return $this->belongs_to('User', 'id');
}
public function child(){
return $this->hasMany('Message', 'parent');
}
public function parent(){
return $this->belongs_to('Message', 'id')
}
}
So if you have a conversation you have a message, this message may or may not have a child or a parent and always has a user which made the message. So if i want to save a conversation this way, how would i do this?
For example, i have to following conversation:
John (1) says: Hi all!
Mark (3) responds: Hey there!
Hans (4) responds: Hi john
Peter(2) responds: Goodmorning.
Now i am john and i would like to save this conversation as below:
id | user | message | parent
========================================
1 | 1 | Hi, All! | NULL
2 | 3 | Hey there! | 1
3 | 4 | Hi john | 1
4 | 2 | Goodmorning. | 1
I can save them all separately but i figure there has to be a better way than below:
$parent = NULL;
foreach($messages as $message){
$model = new Message;
$model->user = $message['user'];
$model->message = $message['value'];
if(!is_null($parent)){
$model->parent = $parent;
}
$model->save();
if(is_null($parent)){
$parent = $model->id;
}
}
The initial problem I saw was that you are saying that the message's parent is always itself, you need to specify an additional unsigned integer to relate on. Here's one example:
public function parent(){
return $this->belongs_to('Message', 'parent_id')
}
You need to use that same 'parent_id' for the children as well:
public function children(){
return $this->hasMany('Message', 'parent_id');
}