Laravel - how to change table in orWhere method? - php

I want to do something like this:
$posts= Status::where('users_id',$user->id)->orWhere(DB::table('user_status_share.user_id', $user->id))->orderBy('created_at', 'DESC')->get();
But I'm getting an error: strtolower() expects parameter 1 to be string, object given - how can I change the table in "orWhere" method? Is this possible? If not - how to use 2 tables in one query?
Schema (Status):
public function up()
{
Schema::create('users_status', function (Blueprint $table) {
$table->increments('id')->unique();
$table->longText('status_text');
$table->integer('users_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users_status');
}
Schema (StatusShare):
public function up()
{
Schema::create('user_status_share', function (Blueprint $table) {
$table->increments('id');
$table->integer('status_id');
$table->integer('user_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('user_status_share');
}
Model Status:
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class Status extends Model
{
public $timestamps = true;
protected $table = 'users_status';
protected $guarded = ['id'];
public function comments()
{
return $this->hasMany(StatusComments::class);
}
public function likes()
{
return $this->hasMany(StatusLikes::class);
}
public function shares()
{
return $this->hasMany(StatusShare::class);
}
}
Model StatusShare:
<?php
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class StatusShare extends Model
{
public $timestamps = true;
protected $table = 'user_status_share';
protected $guarded = ['id'];
public function status()
{
return $this->hasOne(Status::class);
}
}

I think you should try something like this
tweak it , i didnt test it
$posts = DB::table('status')->where('users_id',$user->id)->orWhere(function ($query) use ($user) {
$query->table('user_status_share')->where('user_id', $user->id);
})
->get();
can you share more informations because i have a feeling that these can be reached in a simple way using relations (show us database structure and relations in your models)

Related

laravel Pivot table for Many to Many relation without laravel convention

I have 2 model user and team, every team can have multiple users and each user can be in any team , so I wanna make a many to many relation.
I'm trying to customize something , I don't wanna use the laravel convention for pivot table.
Here is my User Migration:
class CreateUsersTable extends Migration
{
protected $collection = "table_users";
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->string('_id');
$table->string('username')->unique();
$table->string('password');
}
}
}
And here is my Team Migration :
class CreateTeamTable extends Migration
{
protected $collection = "table_team";
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->string('_id');
$table->string('name')->unique();
}
}
}
So my problem is when I want to create method for the relation in User Model and Team Model.
in Team Model :
public function users()
{
return $this->belongsToMany(User::class, '??', '??' , '??'); // what should I insert in '??'
}
in User Model :
public function teams()
{
return $this->belongsToMany(Team::class, '??', '??' , '??'); // what should I insert in '??'
}
And also how to create Pivot table without using any convention:
pivot table that I created so far:
class CreateUsersTeamTable extends Migration
{
protected $collection = "team_user_pivot";
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create( $this->collection
, function (Blueprint $table) {
$table->id();
$table->string('??'); // please help me to fill this field
$table->string('??'); // please help me to fill this field
$table->timestamps();
});
}
There are '??' in User Model and Team model and Pivot table . help me to fill up each of them
It's not quite as simple as filling in the fields, as you're using a string for the foreign key as well as not follwing the standard namig conventions.
create_team_user_pivot
protected $collection = "team_user_pivot";
public function up()
{
Schema::create($this->collection, function (Blueprint $table) {
$table->id();
$table->string('team__id')->references('_id')->on('teams');
$table->string('user__id')->references('_id')->on('users');
$table->timestamps();
});
}
You also need to edit the models:
User
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public $table = 'table_users';
public $incrementing = false;
public $keyType = 'string';
protected $primaryKey = '_id';
protected $fillable = [
"_id",
"username",
"password"
];
public function teams()
{
return $this->belongsToMany(Team::class, 'team_user_pivot', 'user__id', 'team__id');
}
}
Team
class Team extends Model
{
use HasFactory;
public $table = 'table_teams';
public $incrementing = false;
public $keyType = 'string';
protected $primaryKey = '_id';
protected $guarded = [];
public function users()
{
return $this->belongsToMany(User::class, 'team_user_pivot', 'team__id', 'user__id');
}
}
you have to create another model with migration
class UserTeam extends Model
{
public $timestamps = false;
protected $table = 'user_has_team';
protected $fillable = ['user_id', 'team_id'];
}
in your team model
public function users()
{
return $this->belongsToMany(User::class, 'user_has_team', 'user_id', 'team_id');
}
in your user model
public function teams()
{
return $this->belongsToMany(Team::class, 'user_has_team', 'team_id', 'user_id');
}

Laravel: user id is not added as Foreignkey

I want that a user can create e.g. a football club. When the logged in user creates the club (with an Input-field) the foreignkey should automatically appear in the table of the club.
User
User Modell
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
public function wgGroup()
{
return $this->hasOne('WgGroup','user_id');
}
}
WgGroup e.g. for example to create a club
WgGroup Controller
class WGController extends Controller
{
public function dashboard()
{
return view('verified.dashboard');
}
public function createWG(Request $request)
{
$wg = new WgGroup();
$wg->wg_name = $request->wg_name;
$wg->user_id = User::find($request['id']);
$wg->save();
if($wg != null){
return redirect()->back()->with(session()->flash('alert-success', 'Your wg are createt'));
}
return redirect()->back()->with(session()->flash('alert-danger', 'Something went wrong!'));
}
}
WgGrup Model
class WgGroup extends Model
{
use HasFactory;
protected $table = 'wg_groups';
protected $fillable = [
'wg_name', 'user_id'
];
public function user() {
return $this->belongsTo('User');
}
}
WgGroup Database
class CreateWgGroups extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('wg_groups', function (Blueprint $table) {
$table->id();
$table->string('wg_name');
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('wg_groups');
}
}
I don't know exactly why the FK user_id is not added directly to the database.
public function user() {
return $this->belongsTo('User');
}
I thought through this function would happen.

Laravel relationship design

I'm working on team management project.
I have a problem with doing relationships.
I want to display users in boards, but also want to look good and easy to read. I already designed relationships but when I saw JSON output of relationships, it was completely messed.
Is there some way how to display relationship data this way?
{
"id": 1,
"name: "Test",
"members": [
{
... user model here
"name": "Peter",
"email": "peter#peter.com",
}
]
}
My migrations:
Boards migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBoardsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('boards', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('boards');
}
}
Membership migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMembershipsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('memberships', function (Blueprint $table) {
$table->increments('id');
$table->integer('board_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('memberships');
}
}
EDIT:
Models
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Board extends Model
{
protected $fillable = ['name'];
public function members() {
return $this->hasMany(Membership::class)->with('user');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Membership extends Model
{
protected $fillable = ['board_id', 'user_id'];
protected $hidden = ['created_at', 'updated_at'];
public function user() {
return $this->hasOne(User::class, 'id', 'user_id');
}
}
You can try to define the relationships in the models as a Many to Many one, i.e.:
class User
{
public function boards()
{
return $this->belongsToMany('App\Board', 'memberships', 'user_id', 'board_id');
}
}
class Board
{
public function members()
{
return $this->belongsToMany('App\User', 'memberships', 'board_id', 'user_id');
}
}
With that relations defined you don't really need a Membership Model if it has not additional fields, and you can write code like that:
User::find($id)->boards
Board::find($id)->members
Board::with('members')->find($id)
You could read also the documentation on Many to Many Relationships

Building a dynamic query of a many-to-many relationship in Laravel 5

I am pretty new to the Laravel Eloquent ORM and am having difficulty building a dynamic query to query products of a category.
I parse the request object and return products according to what vars have been passed through. This is easy enough when I am querying a single Model but I want to know how to build a query dynamically if a category is passed through to. This is easy enough using standard MYSQL and PHP but I am unsure as to how this is achieved in LAravel.
Here is my code:
Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $primaryKey = 'id',
$table = 'products',
$fillable = array('title', 'SKU', 'description', 'created_at', 'updated_at');
public $timestamps = true;
/**
* Get the categories assoicated with the product
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*
*/
public function categories() {
return $this->belongsToMany('App\Category')->withTimestamps();
}
}
Category model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
/**
* Returns all products related to a category
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function products() {
return $this->belongsToMany('App\Product')->withTimestamps();
}
}
Inside my product controller I have this function to get products which calls a method 'filterProduct' in a class called 'filtervars':
public function index(Request $request)
{
return FilterVars::filterProduct($request->all());
}
And here is the filterProduct method:
public static function filterProduct($vars) {
$query = Product::query();
if((array_key_exists('order_by', $vars)) && (array_key_exists('order', $vars))) {
$query = $query->orderBy($vars['order_by'], $vars['order']);
}
if(array_key_exists('cat', $vars)) {
$query = $query->whereHas('categories', function($q) use ($vars){
return $q->where('category_id', $vars['cat']);
});
}
return $query->get();
The product database migration:
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function(Blueprint $table) {
$table->increments('id');
$table->string('title', 75);
$table->string('SKU')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
And the migration which shows the structure of the categories table, the pivot table and foreign keys etc:
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
Schema::create('category_product', function(Blueprint $table) {
$table->integer('product_id')->unsigned()->index();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->integer('category_id')->unsigned()->index();
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->timestamps();
});
}
I had a go at trying to incorporate the 'has' method on the query but this doesn't seem to work. can anyone advise as to where I am going wrong?
Thanks!
May be you need whereHas method
$query = $query->whereHas('categories', function($q) use ($vars) {
$q->where('id', $vars['cat']);
});
EDIT
You should use id column in whereHas method because you apply where condition to categories table, which hasn't category_id column
public static function filterProduct($vars) {
$query = Product::query();
if((array_key_exists('order_by', $vars)) && (array_key_exists('order', $vars))) {
$query = $query->orderBy($vars['order_by'], $vars['order']);
}
if(array_key_exists('cat', $vars)) {
$query = $query->whereHas('categories', function($q) use ($vars){
$q->where('id', $vars['cat']);
});
}
return $query->get();
}

Eloquent relation setup, two foreign keys to same table laravel 5.2

I have been in big problem, I am maintaining eloquent relationship setup in my project where i am having the following relationship:
User info related to login stored in users table.
User profile related information stored in profiles information.
Users address stored in address table
configurations related information stored in configurations like city, state, country
Efforts
Here is the migration and model and their relationship:
Users migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
User Model:
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function profile()
{
return $this->hasOne('App\Profile','user_id');
}
}
Profile migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('profile_id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('lastname')->nullable();
$table->string('firstname')->nullable();
$table->string('gender')->nullable();
$table->string('phonenumber', 20)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('profiles');
}
}
Profile Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
protected $fillable = [
'firstname', 'lastname',
];
public function user(){
return $this->belongsTo('App\User');
}
public function address()
{
return $this->hasOne('App\Address','profile_id');
}
}
Configuration migration table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('configurations', function (Blueprint $table) {
$table->increments('config_id');
$table->string('configuration_name');
$table->string('configuration_type');
$table->string('parent_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('configurations');
}
}
Configuration Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
Address Migration Table:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAddressesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->increments('address_id');
$table->integer('profile_id')->unsigned();
$table->foreign('profile_id')->references('profile_id')->on('profiles')->onDelete('cascade');
$table->string('address')->nullable();
$table->integer('city')->unsigned();
$table->foreign('city')->references('config_id')->on('configurations')->onDelete('cascade');
$table->string('pincode')->nullable();
$table->integer('state')->unsigned();
$table->foreign('state')->references('config_id')->on('configurations')->onDelete('cascade');
$table->integer('country')->unsigned();
$table->foreign('country')->references('config_id')->on('configurations')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('addresses');
}
}
Address Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\Configuration');
}
public function state() {
return $this->belongsTo('App\Configuration');
}
public function country() {
return $this->belongsTo('App\Configuration');
}
}
I have used Eloquent relation setup, two foreign keys to same table to make my project relationship. But unfortunately above code does not generating desire output. Take a look:
If I use the command Auth::user()->profile->firstname it will print user first name. So if i use Auth::user()->profile->address->city it should print city name stored in configuration table, but instead print name it print the id.
Please suggest me the solution.
Thanks,
Well, I found the solution for my own question. Thanks for everyone who think this question have some worth.
Well, we don't nedd to change user or profile, we just need to make some changes in configuration and address model only.
change
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\Configuration');
}
public function state() {
return $this->belongsTo('App\Configuration');
}
public function country() {
return $this->belongsTo('App\Configuration');
}
}
to
class Address extends Model
{
public function profile(){
return $this->belongsTo('App\Profile');
}
public function cityConfiguration() {
return $this->belongsTo('App\Configuration', 'city');
}
public function stateConfiguration() {
return $this->belongsTo('App\Configuration', 'state');
}
public function countryConfiguration() {
return $this->belongsTo('App\Configuration', 'country');
}
}
and change
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
To
class Configuration extends Model
{
public function children() {
return $this->hasMany('App\Configuration','parent_id');
}
public function parent() {
return $this->belongsTo('App\Configuration','parent_id');
}
public function city() {
return $this->hasOne('App\Address', 'city');
}
public function state() {
return $this->hasOne('App\Address', 'state');
}
public function country() {
return $this->hasOne('App\Address', 'country');
}
}
and that's it. Everything is working fine.

Categories