I am trying to make a POST request to add a showroom in the Laravel application. When I try to do it with Showroom model using Eloquent ORM , it shows 500 internal server error. But if I do it with DB query, then it successfully CREATE the showroom. I commented out the db query lines and apply dd debugging and found out table for Showroom Model is null.
This is my controller code -
public function store(ShowroomRequest $request)
{
$showroom = new Showroom([
"name" => $request->get('name'),
"address" => $request->get('address'),
"description" => $request->get('description'),
]);
dd($showroom);
$ret = $showroom->save();
// $name = $request->input('name');
// $address = $request->input('address');
// $description = $request->input('description');
// DB::table('showroom')->insert(
// ['name' => $name, 'address' => $address, 'description' => $description]
// );
return redirect()->route('back.showroom.index')->withSuccess(__('Showroom Added Successfully.'));
}
And this is my model -
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Showroom extends Model
{
protected $fillable = ['name', 'description', 'address'];
protected static $ordersModel = 'App\Models\Order';
protected static $reviewsModel = 'App\Models\Review';
public function Orders()
{
return $this->hasMany(static::$ordersModel, 'showroom_id');
}
public function Reviews()
{
return $this->hasMany(static::$reviewsModel, 'showroom_id');
}
}
Finally this is my db structure -
Can anyone help me to find out what went wrong here? Thanks in advance.
in controller can you assign static values instead of request->get, and see if it saves.
please let me what happens afterwards.
also assign name of table in model like this,
protected $table = 'tablename';
Related
I am trying the new codeigniter 4
Trying to create first app following tutorial
https://codeigniter.com/user_guide/tutorial/news_section.html
My controller method to insert data
public function create()
{
$model = new NewsModel();
if (! $this->validate([
'title' => 'required|min_length[3]|max_length[255]',
'body' => 'required'
])) {
echo view('templates/header', ['title' => 'Create a news item']);
echo view('news/create');
echo view('templates/footer');
} else {
$model->save([
'title' => $this->request->getVar('title'),
'slug' => url_title($this->request->getVar('title'), '-', true),
'body' => $this->request->getVar('body'),
]);
echo view('news/success');
}
}
It is echoing success page but data not inserting into database.
In .env file I used
database.default.hostname = localhost
database.default.database = news_db
database.default.username = root
database.default.password =
database.default.DBDriver = MySQLi
I think db connection working as checked with wrong database details its not working
My model is
<?php namespace App\Models;
use CodeIgniter\Model;
class NewsModel extends Model
{
protected $table = 'news';
protected $allowedFields = ['title', 'slug', 'body'];
public function getNews($slug = false)
{
if ($slug === false) {
return $this->findAll();
}
return $this->asArray()
->where(['slug' => $slug])
->first();
}
}
The error is most likely coming from your Model declaration in the Controller.
$model = new NewsModel();
It should be namespaced.
Try:
$model = new \App\Models\NewsModel();
or
$model = model('NewsModel');
I am suggesting that:
if you haven't you should follow the tutorial strictly by extending the core controller because you did not show that in your code.
use CodeIgniter\Controller;
class News extends Controller
And You didnt use App\Models\NewsModel;
Before instantiating your Model class. You can only do that in the way Ali-coder illustrate.
Again still suggesting you should have use
$request->getPost()
Instead of $this->request->getVar('title')
I am suggesting all this because that is how i wrote mine and it work fine.
I have two models (Categories and Channels) in a Morph Relation with Status (active, inactive).
In the moment of creating a new category or a new Channel I need to assign the active status to the new created element. For that, I need to pass the $type (channel or category) and the id of the "statusable" element.
Here is my CategoryController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\CategoriesRequest;
use App\Profile;
use App\Status;
use Session;
use Auth;
class CategoriesController extends Controller
{
public function store(CategoriesRequest $request)
{
$category = Category::create([
'title' => $request->title,
'slug' => str_slug($request->title, '-'),
'about' => $request->about,
]);
$category->save();
$type = 'categories';
$id = $category->id;
$status = (new Status)->create($id, $type); <-- Hier I am passing the two variables to the function CREATE in Status Model
Session::flash('success', 'Category successfully created!');
return redirect()->route('categories.show', $category->slug);
}
}
And hier the STATUS Model with the CREATE method which receive the two variables
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Status;
Relation::morphMap([
'channels' => 'App\Channel',
'categories' => 'App\Category',
]);
class Status extends Model
{
protected $fillable = [
'status',
'statusable_type',
'statusable_id',
];
public function statusable()
{
return $this->morphTo();
}
public static function create($id, $type)
{ // I do hier dd($id); and dd($type) and the two variables have a value
$status = Status::create([
'statusable_id' => $id,
'statusable_type' => $type,
'status' => 'active', // I get the error here!
]);
$status->save();
return $status;
}
}
I confirmed that the two variables arrived to the CREATE method (I see then if I dd() it) right at the beginning of the method. However two lines after I get this error:
Type error: Too few arguments to function App\Status::create(), 1 passed in C:\laragon\www\streets\app\Status.php on line 41 and exactly 2 expected
What am I doing wrong?
EDIT: I have got myself the solution:
If anybody is interested
I have changed the call in Controller to:
$type = 'categories';
$id = $category->id;
Status::create_status($id, $type);
and then in Status model:
public static function create_status($id, $type)
{
$status = new Status;
$status->statusable_id = $id;
$status->statusable_type = $type;
$status->status = 'active';
$status->save();
return $status;
}
TL;DR
Trying to get three models to interact using eloquent for a rest api.
User - belongsToMany(pulls)
Pull - belongsToMany(user) && belongsToMany(boxes)
Box - belongsToMany(pulls)
The pull_user table is working perfectly, I can just attach a user after I save a pull. Saving a box works fine but the attach doesn't work/enter anything into the pivot table (I get no errors though).
The Problem
I can't get a pivot table that associates two of my models together to attach() after a save. I have the three models listed above, the pivot is working for pull_user but not for pull_box even though the save for box is working perfectly. I am able to save a box without an error but the association just never occurs (no error).
The Code
pull_box.php
class PullBox extends Migration
{
public function up()
{
Schema::create('pull_box', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('pull_id');
$table->integer('box_id');
});
}
public function down()
{
Schema::dropIfExists('pull_box');
}
}
Pull.php
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box');
}
}
Box.php
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull');
}
}
BoxController.php
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
...
]);
$user_id = $request->input('user_id');
...
$box = new Box([
'user_id' => $user_id,
...
]);
$pull = Pull::whereId($pull_id)->first();
if($box->save()){
$pull->boxes()->attach($box->id);
$box->view_box = [
'href' => 'api/v1/box/' . $box->id,
'method' => 'GET'
];
$message = [
'msg' => 'Box created',
'box' => $box,
'pull' => $pull_id
];
return response()->json($message, 201);
}
$response = [
'msg' => 'Box creation error, contact supervisor',
];
return response()->json($response, 404);
}
The Solution
I need to know how I can get this association working. I am going to need to add a new layer in under the pull for Item, but I don't want to move one before I solve this. I think that my problem has to stem from a syntactical/logical error on my part but I can't see it. There are a bunch of questions on SO that are very close to giving me a solution, but after reading them I wasn't able to solve my problem.
Any help is appreciated.
Try renaming your pull_box table to box_pull, pivot tables on laravel must be in alphabetical order. If you want to use custom name on pivot table you have to extends your pivot, for example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class PullBox extends Pivot
{
protected $table = 'pull_box';
}
And your many to many relationships:
class Pull extends Model
{
protected $fillable = ['from', 'to', 'runit_id', 'start_time', 'end_time', 'box_count', 'pull_status', 'audit_status', 'status', 'total_quantity', 'accuracy'];
public function users(){
return $this->belongsToMany('App\User');
}
public function boxes(){
return $this->belongsToMany('App\Box')->using('App\PullBox');
}
}
class Box extends Model
{
protected $fillable = ['user_id','from', 'to', 'runit_id', 'start_time', 'end_time', 'pull_id', 'total_quantity', 'status', 'accuracy'];
public function pulls(){
return $this->belongsToMany('App\Pull')->using('App\PullBox');
}
}
I'm trying to update some values of a related model but after assigning the new values and using save() or push() the values are not updated in database. More than that, execution just stops at those methods and all I can see is a blank page. No errors, no nothing, it just doesn't even reach the return statement. If I use the try-catch, it just skips the save() or push().
Here is the Product model (just without the fields and methods that are not related to what I'm currently trying to do):
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = "products";
public $timestamps = false;
public $fillable = [
...
];
public function userProduct()
{
return $this->belongsTo("\\App\\Models\\UserProduct", "id", "product_id");
}
}
The UserProduct model with fields which I'm trying to update:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserProduct extends Model
{
protected $primaryKey = null;
public $incrementing = false;
protected $table = "user_product";
public $fillable = [
...
"is_featured",
"is_hidden_from_latest"
...
];
public function product()
{
return $this->belongsTo("\\App\\Models\\Product", "product_id", "id");
}
public function pendingProduct()
{
return $this->belongsTo("\\App\\Models\\PendingProduct", "target_product_id", "target_product");
}
}
Code from the controller:
$replaced_product_sku = Input::get("replaced_sku");
$new_product_sku = Input::get("new_sku");
$products = Product::with([
"userProduct" => function($q) {
$q->orderBy("updated_at", "asc");
}
])->where("product_status", "live")->get();
if (!$found_replaced = $products->where("item_sku", $replaced_product_sku)->first()) {
return redirect("admin/content")
->with("danger", "Replaced product was not found.");
}
if (!$found_new = $products->where("item_sku", $new_product_sku)->first()) {
return redirect("admin/content")
->with("danger", "The new featured product was not found.");
}
$found_replaced->userProduct->is_featured = 0;
$found_replaced->userProduct->is_hidden_from_latest = 1;
$found_new->userProduct->is_featured = 1;
$found_new->userProduct->is_hidden_from_latest = 0;
$found_replaced->userProduct->save();
$found_new->userProduct->save();
return redirect("admin/content")
->with("...", "...");
Tried using push() method instead of save() but the only thing that happens is that execution stops at $found_replaced->userProduct->save(); and a blank page is displayed. Also tried something like this:
$found_replaced->update([
"userProduct.is_featured" => 0,
"userProduct.is_hidden_from_latest" => 1
]);
$found_new->update([
"userProduct.is_featured" => 1,
"userProduct.is_hidden_from_latest" => 0
]);
but still without success.
First you have to fix the relations:
In Product model:
public function userProduct()
{
return $this->hasOne("\\App\\Models\\UserProduct", "product_id", "id");
}
In UserProduct model:
public function product()
{
return $this->belongsTo("\\App\\Models\\Product", "product_id", "id");
}
The solution was using this approach:
$found_replaced->update([
"userProduct.is_featured" => 0,
"userProduct.is_hidden_from_latest" => 1
]);
$found_new->update([
"userProduct.is_featured" => 1,
"userProduct.is_hidden_from_latest" => 0
]);
that I've posted in the question, but the mistake was that I was using it wrong, so I've edited it into this and it worked fine:
$found_replaced->userProduct()->update([
"is_featured" => 0,
"is_hidden_from_latest" => 1
]);
$found_new->userProduct()->update([
"is_featured" => 1,
"is_hidden_from_latest" => 0
]);
Seems that save() just doesn't work as expected on relation attributes.
Thank you for your help anyway! ;)
I'm trying to send use models for the first time and running into a confusion. When I run a query, the rules are linked with it, is it supposed to be like that?
Model:
class User extends Elegant
{
public static $table = 'users';
protected $rules = array(
'email' => 'required|email',
'firstname' => 'required',
'lastname' => 'required',
'initials' => 'required|alpha|match:/[A-Z]+/',
'role' => 'required|in:writer_fr,writer_en,reader',
'password' => 'min:6,max:32|same:password2'
);
public static function has_role($role)
{
//$u = new User;
$users = User::where($role, '=', 1)->get(array('firstname', 'lastname'));
return $users;
}
}
Controller
$u = array();
$u['writer_en'] = User::has_role('writer_en');
dd($u['writer_en']);
Which prints out the entire model rules, messages, relationship etc logic. Am I doing something wrong or is this normal?
In your has_role method you are returning User model
public static function has_role($role)
{
//$u = new User;
$users = User::where($role, '=', 1)->get(array('firstname', 'lastname'));
return $users; // <-- User model
}
So, it's dumping the User model and it's doing the right thing as it suppose to do by following code
$u = array();
$u['writer_en'] = User::has_role('writer_en');
dd($u['writer_en']);
Instead of dumping the model, you can use
$user = User::has_role('writer_en');
echo $user->firstname;
echo $user->lastname;