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;
Related
im trying to create a one to one relationship with the table user,student and teacher. The problem is, when i run LARAVEL TINKER, app\user::find('a123')->teacher it displays the b345 data and doesnt display NULL. New in Laravel. Thanks
Below is the table with their PK.
User table
user_id | type
a123 | 1
b345 | 2
Student table
student_id| name
a123 | Danny
Teacher table
teacher_id| name
b345 | Mr.Mark
and this BELOW is the models.
User Model
protected $primaryKey = 'user_id';
public function student(){
return $this->hasOne(student::class,'student_id');
}
public function teacher(){
return $this->hasOne(teacher::class,'teacher_id');
}
Student Model (Teacher model is just the same with teacher_id as PK)
protected $primaryKey = 'student_id';
public function User()
{
return $this->belongsTo(User::class,'user_id');
}
From you description, student should belongs to user, also teach
In User Model
public function student(){
return $this->hasMany(Student::class,'student_id');
}
In Student Model
public function user(){
return $this->belongsTo(User::class,'student_id');
}
I'm learning Laravel right now and I'm stumped on how to get an array of records from one table that belong to a record on another table based on a key.
I have two tables:
titles
-------------------
id | title_name | created_at | updated_at
posts
-------------------
id | titles_id | content
I have the route /{title_name} being controlled by the read() method on my PagesController.php
public function read($title){
$title_name = $title;
$title_id = Title::find($title)->id;
$posts = Title::find($title)->posts;
return view('pages/read')->with([
'title_name' => $title_name,
'title_id' => $title_id,
'posts' => $posts
]);
}
But this doesn't seem to output anything. I have my models setup like this:
Title.php
class Title extends Model
{
// Table Name
protected $table = "titles";
// Primary Key
protected $primaryKey = "title";
// Timestamps
public $timestamps = "true";
// Custom primaryKey
public $incrementing = false;
//relationship
public function posts(){
return $this->hasMany('App\Post', 'titles_id')->orderBy('created_at', 'desc');
}
}
Post.php
class Post extends Model
{
// Table Name
protected $table = "posts";
// Primary Key
protected $primaryKey = "id";
// Timestamps
public $timestamps = "true";
//relationship
public function titles(){
return $this->belongsTo('App\Title');
}
}
I think the problem is that when I do Title::find($title)->post, laravel is trying to find posts where the titles_id = title_name, because I set title_name as the primaryKey, but I need it to be looking for the id column in the Titles table, and not the name...
Alright I will give you an example where I explain everything you do wrong.
Tables:
titles
-------------------
id | title_name | created_at | updated_at
posts
-------------------
id | title_id | content
Not titles_id but title_id, eloquent likes this more.
Your controller:
public function read($titleName){
// The first function argument is the name of the title,
// not the title model.
// Also don't use snake_case in laravel(Except helpers) but camelCase.
// We are not going to use find, you might have set the name as
// primary key, but the id column still exists.
// firstOrFail() means get the first result, if there isn't, throw
// a model not found exception(404).
$title = Title::where('name', $titleName)->firstOrFail();
return view('pages/read')->with([
// You could just do 'title' => $title, and do the rest in the view.
'title_name' => $title->name,
'title_id' => $title->id,
'posts' => $title->posts
]);
}
Title model:
class Title extends Model
{
// $table not needed, laravel knows this(Yes pure magic).
// No, we don't want name as primary key.
// Timestamps is true by default, so we don't need it.
public function posts(){
return $this->hasMany(\App\Post::class)->orderBy('created_at', 'desc');
}
}
Post model:
class Post extends Model
{
// This function should be called title, not titles.
public function title(){
return $this->belongsTo(App\Title::class);
}
}
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.
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();
I have a table without 'primary ID', ex.
+---------+----------+------------+------------+
| user_id | point_id | created_at | updated_at |
+---------+----------+------------+------------+
And I have records:
1 ..| 200 | (date) | (date)
14 | 300 | (date) | (date)
1 ..| 200 | (date) | (date)
Now I want delete only one record to get:
1 ..| 200 | (date) | (date)
14 | 300 | (date) | (date)
I tryied:
UserPoint::where( 'point_id', $reqId )->where( 'user_id', $userId )->first()->delete();
But it always remove all record with this params ... Anyone can help?
EDIT: My UserPoint model
use Illuminate\Database\Eloquent\Model;
class UserPoint extends Model {
protected $table = 'point_user';
public function scopeUsed($query){
return $query->where('amount', '<', 0);
}
public function scopeEarned($query){
return $query->where('amount', '>', 0);
}
public function about(){
return $this->hasOne('\App\Point', 'id', 'point_id');
}
}
The way you are trying to achieve this deletion is somewhat wrong as it does not follow the rules of data integrity . Deleting a child table in your case would impose what we call an orphaned table.
However the correct way of deleting that record would be to first associate this table to its parent related table in this case as below:
Class User extends Model {
public function points() {
return $this->hasMany(UserPoint::class)
}
}
then in your UserPoint Class or Model you then need to map your relation.
class UserPoint extends Model {
protected $table = 'point_user';
// I have added this part
public function users() {
return $this->belongsTo(User::class)
}
public function scopeUsed($query){
return $query->where('amount', '<', 0);
}
public function scopeEarned($query){
return $query->where('amount', '>', 0);
}
public function about(){
return $this->hasOne('\App\Point', 'id', 'point_id');
}
}
This way you when deleting the Model or Item you can simply do the below:
// Inject your User in the constructor or function - lets say you names it User $user
$user->points->delete();
I suggest you also look at Eloquent's association and sync methods when working with relations this way you always know that the related Models are on sync and there re no orphaned children in the database which in Enterprise Design is a huge problem as accuracy and Data intergrity is everything .