I have a database tables Users, Listings
Users table:
id, name, email, password
Listings table:
id, title, seller_id
Listing migration:
public function up()
{
Schema::create('listings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->bigInteger('seller_id')->unsigned();
$table->timestamps();
$table->foreign('seller_id')->references('id')->on('users')->onDelete('cascade');
});
}
User model:
public function listings()
{
return $this->hasMany(Listing::class);
}
Listing model:
public function seller()
{
return $this->belongsTo(User::class, 'seller_id', 'id');
}
ListingResource:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ListingResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
ListingsController:
public function index()
{
return ListingResource::collection(auth()->user()->listings()->latest());
}
I keep getting this error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'listings.user_id' in 'where clause' (SQL: select * from listings where listings.user_id = 1 and listings.user_id is not null order by created_at desc limit 1)"
How come it returns the query with user_id as the foreign key, even though I specifically put 'seller_id' as the foreign key inside the User.php model?
I have tried to put:
public function listings()
{
return $this->hasMany(Listing::class, 'seller_id');
}
As I have read that this could work, but this generates the following error:
"Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::mapInto()"
While the error message isn't the most clear for this, what is essentially happening is that {Resource}::collection($collection); requires a Collection to function, but at the current point in it's lifecycle, your argument is a Builder instance. To fix this, simply pass a closure to convert your Builder to a Collection:
public function index(){
return ListingResource::collection(auth()->user()->listings()->latest()->get());
}
->latest() is shorthand for ->orderBy('created_at', 'DESC'); (or id, not sure which it uses internally), but doesn't actually execute the query. Simply adding ->get() will convert the Builder to a Collection and allow this resource to work.
On another note, the original error was being caused by missing seller_id in your listings() function on your User model. The foreign id of any relationship is guessed by Laravel based on the Model name (User translates to user_id), but since you're using seller_id, you need to specify that in both the original relationship and in the inverse definition. You figured that out, but a quick explanation is always helpful.
Related
This error has been posted here several times but I'm encountering something a little different. I have two Tables named users and user_type. And users uses a foreign key from user_type. I have to fetch all users and their types, I'm using Laravel's Eloquent ORM to define relationships, this is a one to one relation.
Users Model:
/**
* Get the user type that user has.
*/
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
UserType Model:
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'ut_id';
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasOne('App\Models\Users', 'user_type_id', $this->primaryKey);
}
Fetching Controller:
$users = Users::all()->users;
According to Laravel ORM one-to-one I can access this method as a property, but it's showing me the defined error. I've also tried to access it as a method but it's saying:
Method Illuminate\Database\Eloquent\Collection::users does not exist.
I've also tried to fetch them by join() but it's returning only a few users, I don't know why:
$users = Users::where('id', '>', '0')
->join('user_type', 'user_type.ut_id', '=', 'users.id')
->select([
'user_type.ut_name',
'users.*'
])->get();
Can someone tell me what I'm doing wrong?
P.s: I just want to show all the users with their respective types
You had missed the exact foreign key between your users table and usertypes table.
First, you defined the that the foreign key of your user table is 'ut_id' base of what you had in your belongsTo relationship. On this one
/**
* Get the user type that user has.
*/
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
Second is that, in your user type model, you used a foreign key to user table named 'user_type_id', which is at first you named it as 'ut_id' in your users table. On this one
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'ut_id';
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasOne('App\Models\Users', 'user_type_id', $primaryKey);
}
You have to match this foreign keys you used to solve your problem.
Now, to fetch your all user with their types, your query should look like this.
$users = Users::with('users')->get();
assuming that your user table has this relationship
public function users(){
return $this->belongsTo('App\Models\UserType', 'ut_id', 'id');
}
and your user types model has this relationshio
public function users(){
return $this->hasOne('App\Models\Users', 'ut_id', $this->primaryKey);
}
in User model
public function type(){
return $this->hasOne(UserType::class, 'id');
}
in UserType Model
public function users(){
return $this->belongsToMany(User::class, 'id');
}
Your relations seem to be wrong.
Users links to UserType with id to ut_id, but userType links to User with id to user_type_id
I'm pretty sure that it should be this for userTypes
/**
* Get the user associated with the user type.
*/
public function users(){
return $this->hasMany('App\Models\Users', 'id', 'user_type_id');
}
and then this for Users
public function userTypes(){
return $this->belongsTo('App\Models\UserType', 'user_type_id', 'id');
}
Then you can eager load for all the results you want...
$users = Users::where('id', '>', '0')
->with('userTypes')
->get();
Considering this tables: person and employee to which connected to person by person_id. This person_id is also the Primary & Foreign key of employee table. Thus in my migrations, i have this:
Schema::create('employees', function (Blueprint $table) {
$table->bigIncrements('person_id');
$table->foreign('person_id')->references('id')->on('persons')->onDelete('cascade');
});
and my show method is like this one
public function show(Employee $employee){
dd($employee->person_id);
$employee = Employee::where('person_id', $employee->person_id)->orderBy('employee_number', 'asc')->join('persons', 'employees.person_id', '=', 'persons.id')->first();
return view('employee.show', compact('employee'));
}
But i am experiencing this issue:
Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: select * from `employees` where `id` = 5 limit 1)
Does the query is not aware of the column i am using?
Change the primary key in the Employee model
class Employee extends Model
{
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'person_id';
public function person()
{
return $this->belongsTo('App\Employee', 'person_id', 'person_id');
}
}
Then query using find
Employee::find($employee->person_id)->with('person')->first();
orderBy and first are redundant on one result queries
And if you want to return the Employee with the Person, just access the relationship object (employee is returned from route model binding)
public function show(Employee $employee) {
$person = $employee->person;
return view('employee.show', compact('employee', 'person'));
}
Hope this helps
I have three related models.
1.User model
public function users_wishlst(){
return $this->hasMany('App\Users_wishlst');
}
2.Product Model
public function users_wishlst(){
return $this->belongsTo('App\Users_wishlst');
}
3.Users_wishlst model
public function user(){
return $this->belongsTo('App\User');
}
public function product(){
return $this->hasMany('App\Product');
}
in users_wishlsts table i have the followibg columns
id
user_id
product_id
I want to get the product info of an users wishlist. I have tried this
public function showWishList(){
$id= Auth::id();
$WishList = wishlist::with('product')->where(['user_id'=>$id])->get();
return json_encode($WishList);
}
But this gives me the following error
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'products.users_wishlst_id' in 'where clause' (SQL: select * from
products where products.users_wishlst_id in (1, 2, 3))
what is the problem
Without knowing all about your database structure this seems like a problem with your foreign keys. Eloquent tries to automatically guess the key. Based on the error it seems like your products table doesn't contain a users_wishlst_id column (maybe you named it different?). Try looking at you Database and give Laravel the correct foreign_key.
https://laravel.com/docs/5.3/eloquent-relationships#one-to-many
I'm having a hard time resolving this error.
My models:
User Model:
class User extends Model{
public function requests()
{
return $this->hasMany('App\Models\TeamRequest','requested_user_id');
}
}
TeamRequest Model:
class TeamRequest extends Model {
public function requested_user()
{
return $this->belongsTo('App\Models\User', 'requested_user_id');
}
}
Now, I am trying this query:
UserModel::whereHas('requests',function($query) use ($team_id){
$query->where('team_id',$team_id)
->get();
});
And, I'm getting an error:
Column not found: 1054 Unknown column 'users.id' in 'where clause'
(SQL: select count(*) from team_requests where
team_requests.requested_user_id = users.id)
Why am I getting this error?
Schema:
users table
primary key - id
varchar - email
varchar - password
team_requests table
primary key - id
integer - requested_user_id
I have other columns but I believe they do are not of effect.
Your problem is that you're calling get() inside the closure passed to your whereHas(). The closure is used to add constraints to a subquery that will be used to determine if your user has requests. You're only supposed to add constraints to the query inside the closure, you don't want to actually execute that query. If you execute the query inside the closure, you'll get an error (as you've seen) because it is supposed to be a subquery, and does not have all the information required to execute properly.
Your code should be:
UserModel::whereHas('requests', function ($query) use ($team_id) {
$query->where('team_id', $team_id);
});
A Venue has many Subscriptions.
A Subscription has many Subscribers (User).
Theres a pivot table, containing the relation between user_id and subscription_id.
How can I get all Subscribers from a Venue?
I have tried with:
class Venue {
/**
* Members
*/
public function members() {
return $this->hasManyThrough('App\User', 'App\Subscription');
}
}
But it fails with MySQL error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.subscription_id' in 'on clause' (SQL: select `users`.*, `sub
scriptions`.`venue_id` from `users` inner join `subscriptions` on `subscriptions`.`id` = `users`.`subscription_id` where `
users`.`deleted_at` is null and `subscriptions`.`venue_id` = 1)
How my Subscription model look:
`Subscription`
class Subscription extends Model {
protected $table = 'subscriptions';
/**
* Subscripers
*/
public function subscribers() {
return $this->belongsToMany('App\User');
}
/**
* Venue
*/
public function venue() {
return $this->belongsTo('Venue');
}
}
Simple question: Why are you using a third model for Subscriptions? It sounds like a normal n:m relation between User and Venue, as already written in the comments above.
class User {
public function venues() {
return $this->belongsToMany('App\Venue');
}
}
class Venue {
public function users() {
return $this->belongsToMany('App\User');
}
}
This constellation actually needs three tables, which are (i gave each model a column name):
users
- id
- name
venues
- id
- name
user_venue
- user_id
- venue_id
But to access the relations, you can simply use the Eloquent magic:
// List of all venues (as Venue models) that are in relation with User with id $id
$venues = User::find($id)->venues()->get();
// Returns the alphabetically first user that has a relation with Venue with id $id
$user = Venue::find($id)->users()->orderBy('name', 'asc')->first();
If you need to store additional information in the pivot table (e.g. when the relation has been established), you can use additional pivot fields:
user_venue
- user_id
- venue_id
- created_at
class User {
public function venues() {
return $this->belongsToMany('App\Venue')->withPivot('created_at');
}
}
class Venue {
public function users() {
return $this->belongsToMany('App\User')->withPivot('created_at');
}
}
// Returns the date of the relations establishment for the alphabetically
// first Venue the User with id $id has a relation to
$created_at = User::find($id)->venues()->orderBy('name', 'asc')->first()->pivot->created_at;
I've never tried to do whatever you are trying to do there, because it seems (with the current information) conceptually wrong. I also don't know if it is possible to set up an own model for a pivot table, but I think it should work if the pivot table has an own primary id column. It could probably be helpful if you've a third model that needs to be connected with a connection of two others, but normally that doesn't happen. So try it with pivot tables, like shown above, first.
Alright, I still don't see a good use case for this, but I can provide you a query that works. Unfortunately I wasn't able to get an Eloquent query working, but the solution should be still fine though.
class Venue {
public function members($distinct = true) {
$query = User::select('users.*')
->join('subscription_user', 'subscription_user.user_id', '=', 'users.id')
->join('subscriptions', 'subscriptions.id', '=', 'subscription_user.subscription_id')
->where('subscriptions.venue_id', '=', $this->id);
if($distinct === true) {
$query->distinct();
}
return $query;
}
}
The relation can be queried just as normal:
Venue::find($id)->members()->get()
// or with duplicate members
Venue::find($id)->members(false)->get()