Laravel 8 unable to get id from created model 'extended Pivot' - laravel

have an issue
unable to get id from the created model. I check database row created normally
$productStoreLink = ProductStoreLink::create([
'product_id' => $item->id,
'store_id' => $store['id'],
'code' => $store['code']
]);
$productStoreLink->id;
In array dd($productStoreLink)
"product_id" => 1
"store_id" => "2"
"code" => "5411183083684"
"updated_at" => "2021-04-01T09:27:38.000000Z"
"created_at" => "2021-04-01T09:27:38.000000Z"
I have mode. Yeah, this model has extends Pivot, but this is for more difficult operations.
QUESTION:
I wanna receive id from collection after creating a model. $productStoreLink->id in first codeblock.
Real to get id from this model?
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;
class ProductStoreLink extends Pivot
{
use HasFactory;
use SoftDeletes;
protected $fillable = [
'id',
'store_id',
'product_id',
'store_id',
'code',
'created_at',
'updated_at',
'deleted_at',
];
public function price()
{
return $this->hasOne('App\Models\ProductStorePrices','product_store_link_id','id');
}
public function prices()
{
return $this->hasMany('App\Models\ProductStorePrices','product_store_link_id','id');
}
}

Related

Cannot return null for non-nullable field - rebing/graphql

I have a problem with GraphQL(rebing-graphql)/Larvel app. App works fine when I query normal GraphQL query(single not nested), but when I query nested one, I face "debugMessage":"Cannot return null for non-nullable field \"Make Type.name\".
Normal query which works fine:
{model{id,name}}
Nested query that I want to execute:
{model{id,name,make_id{id,name}}
Where am I made mistake?
Thanks in advance.
Make Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
class Make extends Model
{
use HasFactory;
protected $fillable = [
'name',
'logo',
'website',
];
public function models()
{
return $this->hasMany(\App\Models\Model::class);
}
}
Model Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model as MModel;
class Model extends MModel
{
use HasFactory;
protected $fillable = [
'make_id',
'name',
'website',
];
public function make()
{
return $this->belongsTo(Make::class);
}
}
MakeQuery (Graphql part)
<?php
namespace App\GraphQL\Queries;
use App\Models\Make;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;
class MakeQuery extends Query
{
protected $attributes = [
'name' => 'Make Type',
'description' => 'Fetch Make Query'
];
public function args(): array
{
return ["id" => ['type' => Type::int()]];
}
public function type(): type
{
return Type::listOf(GraphQL::type('make'));
}
public function resolve($root, $args)
{
if (isset($args['id'])) {
return Make::where("id",$args['id'])->get();
}
return Make::all();
}
}
MakeType
<?php
namespace App\GraphQL\Types;
use App\Models\Make;
use Rebing\GraphQL\Support\Facades\GraphQL;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Type as GraphQLType;
class MakeType extends GraphQLType
{
protected $attributes = [
'name' => 'Make Type',
'description' => 'Make API Type',
'model' => Make::class
];
public function fields(): array
{
return [
"id" => [
'type' => Type::nonNull(Type::int()),
'description' => 'Make ID'
],
"name" => [
'type' => Type::nonNull(Type::string()),
'description' => 'Make ID'
],
"logo" => [
'type' => Type::nonNull(Type::string()),
'description' => 'Make ID'
],
"website" => [
'type' => Type::nonNull(Type::string()),
'description' => 'Make ID'
]
];
}
}
ModelQuery
<?php
namespace App\GraphQL\Queries;
use App\Models\Model;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;
class ModelQuery extends Query
{
protected $attributes = [
'name' => 'Model Type',
'description' => 'Fetch Model Query'
];
public function args(): array
{
return [
"id" => ['type' => Type::int()]
];
}
public function type(): type
{
return Type::listOf(GraphQL::type('model'));
}
public function resolve($root, $args)
{
if (isset($args['id'])) {
return Model::where("id", $args['id'])->get();
}
return Model::all();
}
}
ModelType
<?php
namespace App\GraphQL\Types;
use App\Models\Make;
use App\Models\Model;
use Rebing\GraphQL\Support\Facades\GraphQL;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Type as GraphQLType;
class ModelType extends GraphQLType
{
protected $attributes = [
'name' => 'Model Type',
'description' => 'Model API Type',
'model' => Model::class
];
public function fields(): array
{
return [
"id" => [
'type' => Type::nonNull(Type::int()),
'description' => 'Model ID'
],
"make_id" => [
'type' => GraphQL::type('make'),
'description' => 'Model_ID'
],
"name" => [
'type' => Type::nonNull(Type::string()),
'description' => 'Model Name'
],
"website" => [
'type' => Type::nonNull(Type::string()),
'description' => 'Model website'
]
];
}
}
There are several things that you have to done to get your code works:
First: Be sure that your tables are full and have valid key relations.
Second: In ModelType change make_id to makeId.
Third: Reload composer autoload with composer dump-autoload.
Finally: In your Model Model it's better to define a column like below:
public function makeId()
{
return $this->belongsTo(Make::class, 'make_id', 'id');
}
I hope these steps would help you.

How to seed 2 tables that are related to each other in Laravel 8

So I have 2 tables one is the User table and the other is the related UserProfile table. I wanted to fill them with dummy data but I cant get it to work that when I run the seeder it will fill both tables. For now it will fill the User table with dummy data only.
Solution found(any sugestions are welcome)
User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\UserProfile;
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable, HasApiTokens;
protected $table = 'user';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
public function profile()
{
return $this->hasOne(UserProfile::class, 'user_id');
}
}
UserProfile.php
namespace App\Models;
use App\Models\User;
class UserProfile
{
protected $table = 'user_profile';
protected $fillable = [
'user_id',
'firstname',
'lastname',
];
public function user()
{
return $this->belongsTo(User::class, 'id');
}
}
UserFactory.php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0,1),
'role' => mt_rand(0,5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
}
}
UserProfileFactory.php
namespace Database\Factories;
use App\Models\UserProfile;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserProfileFactory extends Factory
{
protected $model = UserProfile::class;
public function definition()
{
return [
'user_id' => User::Factory(),
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'default_language' => 'en',
];
}
}
DatabaseSeeder.php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
//solution
User::factory(100)->hasProfile(1, function (array $attributes, User $user) {
return ['firstname' => $user->name];
})->create();
}
}
Could you give this a try:
public function definition()
{
$user = [
'name' => $this->faker->firstName,
'email' => $this->faker->unique()->safeEmail,
'active' => mt_rand(0, 1),
'role' => mt_rand(0, 5),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
];
UserProfile::create([
'user_id' => $user->id
//any other extra data you have in the user_profiles table
]);
return $user;
}
You need to use for method, Belongs To Relationships
UserProfile::factory()
->for(User::factory()->state([
'name' => 'name', // optional
...
]), 'profile')->state([
'firstname' => 'firstname', // optional
...
])->create();
or
$users = User::factory()->count(100)->create();
foreach ($users as $key => $user) {
UserProfile::factory()
->for($user, 'profile')
->create();
}

Attempt to read property "price" on null in laravel?

I am trying to make order management system. for that i make 2 tables orders and orderitems for order.
I want to get price of selected product through relationship.
This is my OrderController
public function store(Request $request)
{
$product = Product::all();
$order = Order::create([
'user_id' => $request->input('user_id'),
'total' => 1,
]);
$size = count(collect($request)->get('quantity'));
for ($i = 0; $i < $size; $i++) {
$orderitem = Orderitem::create([
'order_id' => $order->id,
'product_id' => $request->get('product_id')[$i],
'quantity' => $request->get('quantity')[$i],
'price' => $order->$product->price,
'total' => 3,''
]);
}
return redirect()->route('orders.index');
}
and this is my order model.
protected $table = "orders";
protected $fillable = [
'user_id',
'total',
];
public function user() {
return $this->belongsTo(User::class);
}
public function product() {
return $this->belongsTo(Product::class);
}
public function orderitem() {
return $this->hasMany(Orderitem::class);
}
This is my Product model
use HasFactory;
protected $table = "products";
protected $fillable = [
'name',
'price',
];
public function order() {
return $this->hasMany(Order::class);
}
and this is my products table
this is my orders table
this is my orderitems table
You are accessing price wrongly. 'price' => $order->$product->price,It should be
'price' => $order->product->price,
Updated
I think you can modify relationship to belongsToMany
Order Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
use HasFactory;
protected $guarded=['id'];
public function product(){
return $this->belongsToMany(Product::class,'order_items')->withPivot('quantity', 'price','total')->withTimestamps();
}
}
Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $guarded=['id'];
}
In your controller method
$order = Order::create([
'user_id' => 1,
'total' => 1,
]);
$order->product()->sync([
1=>['quantity'=>2, 'price'=>20,'total'=>40],
2=>['quantity'=>1, 'price'=>10,'total'=>10],
]);
first you build array like multidimensional array structure like
[
productid=>['quantity'=>value, 'price'=>value,'total'=>value],
productid=>['quantity'=>value, 'price'=>value,'total'=>value],
]
Not sure how your $request data will be i guess you can do the following
$size = count(collect($request)->get('quantity'));
$orderitem=[];
for ($i = 0; $i < $size; $i++) {
$orderitem[$request->get('product_id')[$i]] = [
'quantity' => $request->get('quantity')[$i],
'price' => Product::find($request->get('product_id')[$i])->price,
'total' => 3,
]);
}
then you can pass like
$order = Order::create([
'user_id' => 1,
'total' => 1,
]);
$order->product()->sync($orderitem);
Note:This is just snippet to guide you .You can improve logics better than this

No query results for model [App\Models\Customer] backpack

I am using laravel backpack package and while edit and delete or preview operation I am getting the below error.
No query results for model [App\Models\Customer] record id
I have included the model. What am I am missing?
And one more thing the record id which is showing in the error it is not present in the table, But the backpack list interface is showing. why?
And this table is a master. Any CRUD operation will happen only for its own tbl only not affecting any other tbl.
Below is controller
<?PHP
namespace App\Http\Controllers\Admin;
use App\Models\Customer;
use Illuminate\Support\Facades\DB;
use App\Http\Requests\CustomerRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Carbon\Carbon;
class CustomerCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation
{store as traitstore;}
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation
{update as traitupdate;}
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation
{destroy as traitDestroy;}
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
public function setup()
{
//$this->crud->enableExportButtons();
$this->crud->setModel('App\Models\Customer');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/customer');
$this->crud->setEntityNameStrings('customer', 'customers');
}
protected function setupListOperation()
{
// TODO: remove setFromDb() and manually define Columns, maybe Filters
//$this->crud->setFromDb();
$this->crud->setColumns([
[
'name' => 'company_name',
'label' => 'Company',
'type' => 'text',
],
[
'name' => 'company_address1',
'label' => 'Primary Add',
'type' => 'text',
],
[
'name' => 'primary_contact',
'label' => 'Primary Cont',
'type' => 'text',
],
[
'name' => 'company_city',
'label' => 'city',
'type' => 'text',
]
]);
}
}
Model is
<?PHP
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Customer extends Model
{
use CrudTrait, SoftDeletes;
protected $table = 'customers';
protected $primaryKey = "cust_id";
protected $fillable = [
'company_name',
'company_address1',
'company_address2',
'company_city',
'company_zip',
'company_country',
'company_state',
'company_vat',
'company_id',
'primary_contact',
'technical_contact',
'financial_contact',
'cust_def_time_zone',
'created_at',
'updated_at',
'deleted_at' ];
}
edit setupShowOperation function in CustomerCrudController
add this
Customer::withTrashed()->find(\request()->id);

Testing a controller method that uses related models in laravel

I am working in laravel-lumen. I have two models. An Organization model and an Apikey model corresponding to an organizations and an apikeys table. The column organization_id in the apikeys table is a foreign key referring to the id field of the organizations table.
The model for organizations looks like
<?php
namespace App;
use App\Apikey
use Illuminate\Database\Eloquent\Model;
Class Organization Extends Model {
public $table = 'organizations';
public $fillable = [
'name',
'contact_name',
'contact_phone',
'contact_email',
'address1',
'state',
'city',
'zip',
'country'
];
public function apikeys()
{
return $this->hasMany('App\Apikey');
}
}
The apikeys model looks like this
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Class Apikey Extends Model {
public $table = 'apikeys';
public $fillable = [
'key',
'secret',
'organization_id',
'permissions'
];
}
organization_id in apikeys is a foreign key in the organizations table that refers to the id field of organizations table.
Now I have a controller that generates the api key given an organization_id and the permissions and fills the apikeys table. It looks like this
<?php
use App\Http\Controllers\Controller;
use App\Apikey;
use Illuminate\Http\Request;
public function generateApiKeyGivenOrganizationId(Request $request)
{
$data = $request->all();
// code for generating api key.
$dd = [
'key' => 'generated encrypted key',
'secret' => 'secret',
'organization_id' => $data['organization_id'],
'permissions' => $data['permissions']
];
$xx = Apikey::create($dd);
return response()->json(['status' => 'ok', 'apikey_id' => $xx->id]);
}
}
I want to test this code. I created two model factories like this.
$factory->define(Organization::class, function ($faker) use ($factory) {
return [
'name' => $faker->name,
'contact_name' => $faker->name,
'contact_phone' => '324567',
'contact_email' => $faker->email,
'address1' => 'xxx',
'state' => 'Newyork',
'city' => 'Newyork',
'country' => 'USA'
];
});
$factory->define(Apikey::class, function ($faker) use ($factory) {
return [
'key' => 'xxx',
'secret' => 'xxxx',
'permissions' =>'111',
'organization_id' => 7
});
My testing function looks like this.
public function testApiKeyGeneration ()
{
factory(App\Organization::class)->create()->each(function($u) {
$data = [
'organization_id' => $u->id,
'permissions' => '111'
];
$this->post('/createapikeyfororg' , $data)
->seeJson(['status' => 'ok']);
});
}
The controller works perfectly. It is only in the testing I am having problems. The url '/createapikeyfororg' is the url that invokes the controller method generateApiKeyGivenOrganizationId(). Is this testing procedure correct? I am yet to try it out and I am asking this question on a Saturday because I am really in a hurry. I am a total novice at testing and I am in a hurry and any help would be appreciated.

Resources