Issues with pivot table with Laravel - php

I have a problem with creating pivot table in Laravel. That's the first time I'm using it, and after searching on Internet, I can't manage to fix my issue.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'champions_teams.teams_id' in 'field list' (SQL: select `champions`.*, `champions_teams`.`teams_id` as `pivot_teams_id`, `champions_teams`.`champions_id` as `pivot_champions_id`, `champions_teams`.`champion_id` as `pivot_champion_id` from `champions` inner join `champions_teams` on `champions`.`id` = `champions_teams`.`champions_id` where `champions_teams`.`teams_id` = 1) (View: C:\laragon\www\proyecto-web\resources\views\teams\teamIndex.blade.php)
Following, the way I created my classes "Champions" and "Teams", with my pivot table migration.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\softDeletes;
class Teams extends Model
{
use SoftDeletes;
protected $table = 'teams';
protected $fillable = ['user_id','name','rank','region'];
public function user(){
return $this->belongsTo(User::class);
}
public function champions(){
return $this->belongsToMany(Champions::class)->withPivot('champion_id');
}
public function files(){
return $this->morphMany(File::class, 'model');
}
public function setNameAttribute($value){
$this->attributes['name'] = strtoupper($value);
}
public function getTeamsNameAttribute(){
return $this->name;
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Champions extends Model
{
protected $table = 'champions';
protected $fillable = ['name','health_points','type','role'];
public function teams(){
return $this->belongsToMany(Teams::class)->withPivot('team_id');;
}
public function items(){
return $this->hasMany(Items::class, 'champion_id');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class PivotTables extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('champions_teams', function(Blueprint $table){
$table->unsignedBigInteger('champion_id');
$table->unsignedBigInteger('team_id');
$table->foreign('champion_id')
->references('id')
->on('champions')
->onDelete('cascade');
$table->foreign('team_id')
->references('id')
->on('teams')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
}
}
Thanks for your help ! You can also access the whole code right here : https://github.com/ValentinDelpy/proyecto-web

Many to Many
Since you are not following the name conventions which Laravel expects, you should customize the name of the joining table, the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:
class Champions extends Model
{
public function teams(){
return $this->belongsToMany(Teams::class, 'champions_teams', 'team_id', 'champion_id');
}
}
class Teams extends Model
{
public function champions(){
return $this->belongsToMany(Champions::class, 'champions_teams', 'champion_id', 'team_id');
}
}

Seems You have collision with teams and team.
You model is named Teams (should be Team).
Checkout how to make many to many relations propely:
Laravel docs

Probably Laravel is generating the id from the Model name, so if the Project is brand new, just change it, otherwise, you have to declare the foreign keys name in the belogsToMany function (check https://laravel.com/api/6.x/Illuminate/Database/Eloquent/Concerns/HasRelationships.html#method_belongsToMany).
Also keep in mind that the witPivot function is to let Laravel know the existence of other fields more than the only 2 foreign keys, not the foreign keys themself (check https://laravel.com/api/6.x/Illuminate/Database/Eloquent/Relations/BelongsToMany.html#method_withPivot)

Related

Laravel eloquent inserting data only in Pivot table

Backround information
Using Laravel I'm building an application where I want to link a Company profile to a Station.
Company.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
protected $guarded = [];
protected $table = 'companies';
public function user()
{
return $this->hasMany('App\User');
}
public function station()
{
return $this->belongsToMany('App\Station')->withPivot('company_stations');
}
public function line()
{
return $this->belongsToMany('App\Line');
}
}
Station.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Station extends Model
{
protected $guarded = [];
protected $table = 'stations';
public function lines()
{
return $this->belongsToMany('App\Line');
}
public function company()
{
return $this->belongsToMany('App\Company')->withPivot('company_stations');
}
}
company_stations migration
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCompanyStationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('company_stations', function (Blueprint $table) {
$table->id();
$table->integer('company_id')->unsigned();
$table->integer('station_id')->unsigned();
$table->boolean('following')->default(false);
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('company_stations');
}
}
I also have a migration company_stations, but no Model for it.
The question
I want to create a checkbox on the station view where the currently logged in Company ID is linked to the Station ID in the pivot table to keep track of which stations the company is following and wether the company has completed that station or not.
What would be the easiest and most clean approach to this? Do I make a new Model CompanyStation + controller or can this be filled in from the Company or Station controller?
You can use sync method of belongsTomany relationship.
$station = Station::find($stationid);
$station->company()->sync([1,2,3]); //1,2,3 is the company ids which you're selection through checkbox.
//this will drop all the existing companies except the companies with id 1,2,3. If these ids don't exist it will attach them (still dropping the existing ones).
if you add a column to your piviot table company_stations example: 'completed' you can access it with
foreach ($company->stations as $station) {
dd($station->pivot->completed);
}
you can add that data via
$company->stations()->attach($station->id, ['completed' => true]);
Query it
//only show me completed company stations. (from piviot)
Company::whereHas('stations', function($q) {
$q->where('company_stations.completed', true);
})
->get();

Laravel - How to find foreign key value

first time working with Laravel and PHP. I am trying to insert row in the table profile where the attribute uID is a foreign key referencing to uID on user table, but getting errors. How do I insert just the summary attribute of the profile and set the uID (foreign key) automatically. I can insert users with uID without any problems. Here are my model and controller files. Thanks!
user model
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
// specify which attributes can be filled out during registration
public $timestamps = false;
protected $fillable=['firstname','lastname','email','password',];
public function profile(){
return $this->hasOne(profile::class);
}
}
profile model
namespace App;
use Illuminate\Database\Eloquent\Model;
class profile extends Model
{
//
public $timestamps = false;
protected $fillable = ['summary',];
public function user(){
return $this->belongsTo(user::class);
}
}
profile migration
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
// create profile table
Schema::create('profiles', function (Blueprint $table) {
$table->increments('pID');
$table->timestamp('created_at')->useCurrent();
$table->string('summary')->default('');
$table->unsignedInteger('uID');
$table->foreign('uID')->references('uID')->on('users')->onDelete('cascade');
});
}
}
profile controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\profile;
class ProfileController extends Controller
{
public function create()
{
//
return view('profile.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// used to store user profile after validation
$this->validate($request,[
'summary' => 'required'
]);
$profile = new profile([
'summary' => $request->get('summary'),
'uID' => $request->user()->uID
]);
return redirect()->route('profile.create')->with('success','Profile created');
}
}
Welcome to Laravel :)
On your profile Model on the user method you need to define the foreign key.
public function user(){
return $this->belongsTo(user::class, 'uID');
}
If you don't provide the foreign key, it will look for user_id field.
Alright, a couple of things that could need to be sort out:
Declare your Classes with a capitalised letter. It is Profile not profile. Avoid plurals as well. More on that can be explored reading about PSR-x;
You have deviated from the laravel way in regards to foreign keys. Therefore, you need to specify in your relationship which are the keys to connect with:
Also, notice how I changed your method name from user -> users
public function users()
{
return $this->belongsTo(user::class, 'id', 'uID');
}
As well as for your profile relationship:
public function profiles(){
return $this->hasOne(profile::class, 'uID', 'id');
}
hi put your database here and add forign key to the model

SQLSTATE[42S22]: Column not found: 1054 Unknown column in laravel

I'm trying to make a shopping cart with laravel and am having trouble with one of the methods
this is the error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pedidos__produtos.pedidos_id' in 'where clause' (SQL: select id_produto, sum(total) as Total, count(1) as qtd from pedidos__produtos where pedidos__produtos.pedidos_id = 1 and pedidos__produtos.pedidos_id is not null group by id_produto order by id_produto desc)
I searched the entire code, but I did not refer this field "pedidos_id" anywhere
This error happens when I call "$pedidos[0]->pedido_produtos," in Carrinhocontroller.php
These are the related methods and migrations:
CarrinhoController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Pedidos;
use Illuminate\Support\Facades\Auth;
class CarrinhoController extends Controller
{
function __construct(){
$this->middleware('auth');
}
public function index(){
$pedidos = Pedidos::where([
'id_user' => Auth::id()
])->get();
dd([
$pedidos,
$pedidos[0]->pedido_produtos,
//$pedidos[0]->pedidos_produtos[0]->produto
]);
return view('carrinho.index', compact('pedidos'));
}
}
Pedidos.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pedidos extends Model
{
public function pedido_produtos(){
return $this->hasMany('App\Pedidos_Produtos')
->select( \DB::raw('id_produto, sum(total) as Total, count(1) as qtd'))
->groupBy('id_produto')
->orderBy('id_produto', 'desc');
}
}
Pedidos_Produtos.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pedidos_Produtos extends Model
{
public function produto(){
return $this->belongsTo('App\Produtos', 'id_produto', 'id');
}
}
Migration from Pedidos:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePedidosTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('pedidos', function (Blueprint $table) {
$table->increments('id');
$table->integer('id_user')->unsigned();
$table->foreign('id_user')->references('id')->on('users');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('pedidos');
}
}
and from pedidos_produtos
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePedidosProdutosTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('pedidos__produtos', function (Blueprint $table) {
$table->increments('id');
$table->integer('id_pedido')->unsigned();
$table->integer('id_produto')->unsigned();
$table->decimal('total', 6, 2)->default(0);
$table->timestamps();
$table->foreign('id_pedido')->references('id')->on('pedidos');
$table->foreign('id_produto')->references('id')->on('produtos');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('pedidos__produtos');
}
}
Can Anyone help me with that?
It generates automatically if foreignKey attribute is not defined on hasMany method.
it generates field name from classname_id pattern. Also localKey default value is class PK.
public function hasMany($related, $foreignKey = null, $localKey = null)
You can use like this.
return $this->hasMany('App\Pedidos_Produtos','id_pedido')
The problem you are experiencing is probably to do with this line:
return $this->hasMany('App\Pedidos_Produtos')
If you do not explicitly tell Laravel what the IDs are called on each table when defining a hasMany relationship, it will assume that the id is {table_name}_id which is where the pedidos_id is coming from.
Try adding the foreign and local keys to the hasMany, something like this:
return $this->hasMany('App\Pedidos_Produtos', 'id_pedido', 'id')

Eloquent relationships: cloumn doesn't exist

I'm new to Laravel and am having a bit of a hard time cracking how relationships work. I'm building a simple e-commerce application, where each user has some orders, and order has one or many sub-orders, and each sub-order is linked to only one item (please don't comment on my scheme yet; for now I just need to figure out Eloquent and will be doing refactoring later :) ).
Following are my models:
class Order extends Model
{
//timestamp
protected $created_at;
public function sub_orders() {
return $this->hasMany('App\SubOrder');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class SubOrder extends Model
{
protected $fillable = array('delivery_date', 'quantity', 'total_price', 'delivery_status');
public function item() {
return $this->hasOne('App\Item');
}
public function order() {
return $this->belongsTo('App\Order');
}
}
class Item extends Model
{
//note - slug is kind of categorization and is common to many items
protected $fillable = array('sku', 'name', 'slug', 'unit_price');
}
And here are the migrations:
class CreateOrdersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at');
//foreign keys
$table->unsignedInteger('user_id')->after('id');
$table->foreign('user_id')->references('id')->on('users') ->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('orders');
}
}
class CreateSubOrdersTable extends Migration
{
public function up()
{
Schema::create('sub_orders', function (Blueprint $table) {
$table->increments('id');
$table->date('delivery_date');
$table->decimal('quantity', 5, 2);
$table->decimal('total_price', 7, 2);
$table->enum('delivery_status', ['pending_from_farmer', 'ready_for_customer', 'out_for_delivery', 'delivered']);
//foreign keys
$table->unsignedInteger('order_id')->after('id');
$table->foreign('order_id')->references('id')->on('orders') ->onDelete('cascade');
$table->unsignedInteger('item_id')->after('order_id');
$table->foreign('item_id')->references('id')->on('items') ->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('sub_orders');
}
}
class CreateItemsTable extends Migration
{
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->increments('id');
$table->string('sku')->unique();
$table->string('name');
$table->string('slug');
$table->decimal('unit_price', 5, 2);
});
}
public function down()
{
Schema::dropIfExists('items');
}
}
The problematic expression is why I write App\Order::all()[0]->sub_orders[0]->item in my web.php and get the following error:
SQLSTATE[42703]: Undefined column: 7 ERROR: column items.sub_order_id does not exist
LINE 1: select * from "items" where "items"."sub_order_id" = $1 and ...
^ (SQL: select * from "items" where "items"."sub_order_id" = 1 and "items"."sub_order_id" is not null limit 1)
I don't understand why it's looking for sub_order_id in the items table. And what's the right way to go about doing it?
Overall: define the 1-to-1 relationship using hasOne or belongsTo will affect the target table where Laravel find the foreign key. hasOne assume there is a my_model_id in target table.And belongsTo assume there is a target_model_id in my table.
class SubOrder extends Model
{
public function item() {
return $this->hasOne('App\Item', 'id', 'item_id');
}
}
or
class SubOrder extends Model
{
public function item() {
return $this-> belongsTo('App\Item');
}
}
According to Laravel Doc
class User extends Model
{
/**
* Get the phone record associated with the user.
*/
public function phone()
{
return $this->hasOne('App\Phone');
}
}
Eloquent determines the foreign key of the relationship based on the model name. In the above case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method:
$this->hasOne('App\Phone', 'foreign_key', 'local_key');
Or Defining The Inverse Of The Relationship
class Phone extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
In the example above, Eloquent will try to match the user_id from the Phone model to an id on the User model.
Your SubOrder item has relationship of type OneToOne (hasOne is bidirectional) with an Item.
So Eloquent expects to have sub_order_id in the items table.
So the solution is to define the inverse of this relationship (belongsTo) in the Item model

Laravel - SQLSTATE[42S22]: Column not found: 1054 Unknown column [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Hello im getting this error Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'posts.user_id' in 'where clause' (SQL: select * frompostswhereposts.user_id= 1 andposts.user_idis not null)' and I don't know why if in my database I don't have user_id, I have id_user...
This is my migration table
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('user')->unique();
$table->string('email')->unique();
$table->string('password', 60);
$table->string('img');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::drop('users');
}
}
This other is my posts migration archive
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddPosts extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('nombre');
$table->longText('contenido');
$table->unsignedInteger('id_user');
$table->timestamps();
});
Schema::table('posts', function($table) {
$table->foreign('id_user')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('posts');
}
}
this is my Post model
<?php
namespace NacionGrita;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = "posts";
protected $fillable = ['nombre', 'contenido', 'id_user'];
public function imagenes() {
return $this->belongsToMany('NacionGrita\Imagen');
}
public function categorias() {
return $this->belongsToMany('NacionGrita\Categoria');
}
public function tags() {
return $this->belongsToMany('NacionGrita\Tag');
}
public function user() {
return $this->belongsTo('NacionGrita\User');
}
}
and this is my users Model
<?php
namespace NacionGrita;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Model
{
protected $table = "users";
protected $fillable = [
'user', 'email', 'password', 'img'
];
public function posts() {
return $this->hasMany('NacionGrita\Post');
}
protected $hidden = [
'password', 'remember_token',
];
}
If I change my "posts" table column from id_user to user_id it works but I don't know why I have to change the column name if its supposed to works because I specified the foreigns keys or Im doing something wrong?
Thanks for help
In order to specify the foreign keys, you need to do so in the model when you define the relationships.
From the docs for a belongsTo relationship:
In the example above, Eloquent will try to match the user_id from the Phone model to an id on the User model. 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
In other words, in your Post model where you define the relationship with the User, you need to add a second argument that specifies the foreign key name:
public function user() {
return $this->belongsTo('NacionGrita\User', 'id_user');
}
From the docs for a hasOne and hasMany relationship:
Eloquent assumes the foreign key of the relationship based on the model name. In this case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method:
In other words, in your User model where you define the relationship with the Post, you need to once again add a second argument that specifies the foreign key name:
public function posts() {
return $this->hasMany('NacionGrita\Post', 'id_user');
}
Link to docs: https://laravel.com/docs/5.1/eloquent-relationships

Categories