Data missing in Carbon on Laravel Many to Many relation - laravel

I recently change my database from from MySql to MSSql and I'm having problems with date formats. I changed all models to use $dateFormat = 'Y-m-d H:i:s' and work's fine, but today I'm having problem with a model that have a relation many-to-many with other model.
My database are saving the dates in format Y-m-d H:i:s.000, in this way 2018-08-20 16:01:12.000. I think that eloquent aren't respecting the date format.
I'm using Laravel 5.4 and php 5.6;
Today, I'm getting this error
InvalidArgumentException in Carbon.php line 909:
Data missing
in Carbon.php line 909
at Carbon::createFromFormat('Y-m-d H:i:s.000', '2018-07-19 10:40:21') in Model.php line 3003
The code that are generate the error,
public function getDetailQuiz()
{
$quiz_id = Input::get('quiz_id');
*$quiz = QuizTopic::with('questions.answers')->where('id', $quiz_id)->first();*
foreach ($quiz->questions as $question) {
$answers = [];
$answer_order = 0;
foreach ($question->answers as $i => $answer) {
$answers[] = ['answer' => $answer->description, 'id' => $answer->id, 'action' => 'update'];
if ($question->answer_id == $answer->id) $answer_order = $i;
}
$response['questions'][] = [
'id' => $question->id,
'question' => $question->description,
'correct_answer' => $question->answer_id,
'points' => $question->points,
'answers' => $answers,
'action' => 'update',
'answer_order' => $answer_order,
];
}
$quiz->start_date = Carbon::parse($quiz->start_date)->format('d/m/Y H:i');
$quiz->end_date = Carbon::parse($quiz->end_date)->format('d/m/Y H:i');
$response['quiz'] = $quiz->makeVisible(['award_value', 'type_id', 'start_date', 'end_date'])->toArray();
return response()->json(['result' => $response]);
}
My QuizTopic Model
class QuizTopic extends Model
{
protected $table = 'quiz_topics';
protected $guarded = ['id'];
protected $hidden = [
'created_at',
'updated_at',
'deleted_at',
'created_user_id',
'updated_user_id',
'winner_clerk_id',
'award_value',
'status_id',
'type_id',
'start_date',
'end_date',
'raffle_date',
'fcm_notification_reference',
];
protected $dateFormat = 'Y-m-d H:i';
use SoftDeletes;
public function questions()
{
return $this->belongsToMany('App\Models\QuizQuestion', 'rel_topics_questions', 'topic_id', 'question_id')->withTimestamps();
}
}
My QuizQuestion Model
class QuizQuestion extends Model
{
protected $table = 'quiz_questions';
protected $guarded = ['id'];
protected $hidden = ['created_at', 'updated_at', 'deleted_at','points','pivot','created_user_id','updated_user_id'];
protected $dateFormat = 'Y-m-d H:i:s';
use SoftDeletes;
public function topics()
{
return $this->belongsToMany('App\Models\QuizTopic');
}
public function answers()
{
return $this->belongsToMany('App\Models\QuizAnswer', 'rel_questions_answers', 'question_id', 'answer_id')->withTimestamps();
}
}

From the manual:
By default, timestamps are formatted as 'Y-m-d H:i:s'. If you need to
customize the timestamp format, set the $dateFormat property on your
model. This property determines how date attributes are stored in the
database, as well as their format when the model is serialized to an
array or JSON
(emphasis mine)
Since you're saving your dates as Y-m-d H:i:s.000, you need to set the $dateFormat property in both of your models as such:
protected $dateFormat = 'Y-m-d H:i:s.000';
Change that and try again.

Related

How to store the actual user logged into my database and display it as a created by field for my CRUD?

I have this code in my controller:
public function store(StoreRequest $request)
{
$user = Auth::user();
$request->get('nombre');
$request->get('correo');
$request->get('creado_por');
$creado_por = Auth::user()->id;
$request->validate([
'creado_por' => 'string'
]);
return ComprasNotificacionCancelacion::create([
'nombre' => request('nombre'),
'correo' => request('correo')
]);
}
This is the model:
protected $table = 'compras_notificacion_cancelacions';
protected $primaryKey = 'id';
protected $guarded = ['id'];
protected $fillable = [
'nombre',
'correo',
'creado_por'
];
protected $dates = [
'fecha_creacion',
'fecha_modificacion'
];
Could you help me, please?
Your question is not clear, but what you are trying to do is add logged in user as the creado_por here is how you can achieve that.
public function store(StoreRequest $request)
{
$request->validate([
'creado_por' => 'string'
]);
//here you can use either Auth()->user()->id or $request->user()->id
return ComprasNotificacionCancelacion::create([
'nombre' => $request->nombre,
'correo' => $request->correo,
'creado_por' => $request->user()->id
]);
}
additionally here are somethings you could improve. You can access same Auth()->user() from $request like $request->user().
You don't need the below codes.
$user = Auth::user();
$request->get('nombre');
$request->get('correo');
$request->get('creado_por');
$creado_por = Auth::user()->id;
and if using id as id no need to mention it
protected $primaryKey = 'id';
The way I store the author of an entry is that I have a created_by column in the database and I make sure that contains the right ID inside the model. Here's a trait I use, that I call CreatedByTrait.php and use it on the models that need it:
<?php namespace App\Models\Traits;
use Illuminate\Database\Eloquent\Model;
trait CreatedByTrait {
/**
* Stores the user id at each create & update.
*/
public function save(array $options = [])
{
if (\Auth::check())
{
if (!isset($this->created_by) || $this->created_by=='') {
$this->created_by = \Auth::user()->id;
}
}
parent::save();
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function creator()
{
return $this->belongsTo('App\User', 'created_by');
}
}

Model relationship creation uses the wrong field in Laravel

I want to create a new model using the relationship between a two model module and chapter and they have HasMany relationship between them as follow :
//Module mode
public function chapters()
{
return $this->hasMany(Chapter::class, 'module_slug', 'slug');
}
//Chapters Model
public function module()
{
return $this->belongsTo(Module::class, 'module_slug', 'slug');
}
And here's how I'm storing the models :
$module = Module::create([
'title' => $request->module_title,
'icon' => $request->module_title
]);
$module->chapters()->create([
'pdf_url' => $path,
'title' => $request->chapter_title
]);
The Issue :
The problem I got is that the $module->chapters()->create() is using the id not the slug which I'm specifying as the primary key like this :
//Module model
protected $primaryKey = 'slug';
protected $keyType = 'string';
//Chapters model
protected $primaryKey = 'slug';
protected $keyType = 'string';
I don't know why it uses the id field like this screenshot :
Add this to your models:
public $incrementing = false;

Laravel eloquent: Multiply two columns of two different tables

My Order Model
class Order extends Model
{
protected $fillable = [
'id','user_id', 'erp_id', 'currency_code','ex_rate_with_base','order_status','status','created_at'
];
protected $hidden = ['updated_at',];
public function orderList(){
return $this->hasMany(OrderList::class);
}
public function currency(){
return $this->belongsTo(Currency::class,'currency_code');
}
}
My Currency Model
class Currency extends Model
{
protected $fillable = [
'currency_code','currency_name', 'currency_symbol', 'ex_rate_with_base', 'update_via', 'status',
];
protected $hidden = [
'created_at','updated_at','updated_by','created_by',
];
protected $primaryKey = 'currency_code';
public $incrementing = false;
public function order()
{
return $this->hasMany(Order::class,'currency_code');
}
}
My OrderList Model
class OrderList extends Model
{
protected $fillable = [
'id','order_id', 'product_code', 'qty','unit_price','status',
];
protected $hidden = [
'created_at' ,'updated_at',
];
public function order(){
return $this->belongsTo(Order::class);
}
}
In my Order controller I want to run the query:
$order_history_list = Order::where([['user_id', $user->id], ['updated_at','>', $updated_at]])
->with([
'currency' => function ($query) {
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},
'orderList' => function ($query) {
$query->select('id','order_id', 'product_code', '***order_lists.qty * orders.ex_rate_with_base AS unit_price_with_ex_rate***','status');
}
])->get();
But error is occuring due to the highlighted portion.
Error: Unknown column 'order_lists.qty * orders.ex_rate_with_base' in 'field list'
Please help me with the correct syntax
How can I use column of order table in the sub query ?
Use DB::raw in your select statement and add a join to the 'orderList' $query
$order_history_list = Order::where([['user_id', $user->id], ['updated_at','>', $updated_at]])
->with([
'currency' => function ($query) {
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},
'orderList' => function ($query) {
$query->select('id','order_id', 'product_code', DB::raw('order_lists.qty * orders.ex_rate_with_base AS unit_price_with_ex_rate'),'status')
->join('orders','order_lists.order_id', 'orders.id');
}
])->get();
My Final Query That Worked:
$order_history_list = Order::where([['user_id',$user->id],['updated_at','>',$updated_at]])
->with(['currency'=>function($query){
$query->select('currency_code','currency_symbol','ex_rate_with_base');
},'orderList' => function($query){
$query->select('order_lists.id','order_lists.order_id', 'order_lists.product_code', 'order_lists.qty','order_lists.unit_price',DB::raw('he_order_lists.qty* he_orders.ex_rate_with_base AS unit_price_with_ex_rate'),'order_lists.status')->join('orders','order_lists.order_id', 'orders.id');
}])->get();

Property [comment] does not exist on this collection instance

I'm trying to get data from a column from table comment through the story table via the slug column. I've managed to do it with authors but I think I must be missing something or forgetting something because it is no longer working. I get this error
Exception in Collection.php line 1498: Property [comment] does not exist on this collection instance.
My controller function
public function slug($slug){
$menus_child = Menu::where('menu_id', 0)->with('menusP')->get();
$stories = Story::where('slug', $slug)->get();
$slug = $slug;
// I used this to get the author's email going through the slug from
// story table
$story = Story::with('author')->where('slug', $slug)->first();
$name = $story->author->first()->email;
// I would like to get the name in the comment table by going through
// the slug from the story table
$comment = Story::with('comment')->where('slug', $slug)->get();
$test = $comment->comment->first()->name;
return view('open::public.single-story', compact('menus_child', 'stories', 'slug'));
}
my Comment.php
namespace App\Modules\Authors\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $fillable = array('name', 'comment');
protected $guarded = array('id');
protected $table = 'comments';
//Validation rules
public static $rules = array(
'name' => '',
'comment' => ''
);
public function story(){
return $this->belongsToMany('App\Modules\Authors\Models\Story', 'comment_story', 'comment_id', 'story_id');
}
}
my Story.php
class Story extends Model
{
protected $fillable = array('title', 'content', 'type', 'slug');
protected $guarded = array('id');
protected $table = 'story';
//Validation rules
public static $rules = array(
'title' => '',
'content' => '',
'type' => ''
);
public function slug($title){
$this->attributes['title'] = $title;
$this->attributes['slug'] = Str::slug($title);
}
public function author(){
return $this->belongsToMany('App\Modules\Authors\Models\Author', 'author_story', 'story_id', 'author_id');
}
public function comment(){
return $this->belongsToMany('App\Modules\Authors\Models\Comment', 'comment_story', 'story_id', 'comment_id');
}
}
With some help from dparoli I managed to do it. I can't believe it to me so long to figure it out.
I changed
$comment = Story::with('comment')->where('slug', $slug)->get();
$test = $comment->comment->first()->name;
to
$comment = Story::with('comment')->where('slug', $slug)->first();
$test = $comment->comment->toArray();
and I added test to
return view('open::public.single-story', compact('menus_child', 'stories', 'slug', 'test'));
and then added
#foreach($test as $t)
<h1>{!! $t['name'] !!}</h1>
<p>{!! $t['comment'] !!}
#endforeach
to my view
Try to change this:
//here you get a collection of stories
$comment = Story::with('comment')->where('slug', $slug)->get();
To this:
//here you get a single story
$comment = Story::with('comment')->where('slug', $slug)->first();
I give you a different approach to try
$comments = Comment::with(['story' => function ($query) {
$query->where('slug', '=', $slug);
}])->get();
Give this a go if it works for what you are trying to accomplish.

laravel eloquent doesn't use protected table name

In my model i added protected $table, but when i'm going to use it laravel does't use it. This is my role models:
class Role extends Model
{
protected $table = 'role';
protected $primaryKey = 'ROLE_ID';
protected $casts = [
'ACTIVE' => 'boolean',
];
protected $fillable = [
'ROLE', 'ACTIVE', 'TYPE'
];
public $timestamps = false;
public function groups()
{
return $this->belongsToMany(Group::class, GroupRole::class, 'ROLE_ID', 'GROUP_ID');
}
}
And this is Group model:
class Group extends Model
{
protected $table = 'groups';
protected $primaryKey = 'GROUP_ID';
protected $fillable = [
'GROUP_ID', 'GROUP_NAME', 'PARENT_GROUP', 'ACTIVE'
];
protected $casts = [
'ACTIVE' => 'boolean',
];
public $timestamps = false;
public function type()
{
return $this->belongsTo(GroupType::class, 'TYPE', 'TYPE_ID');
}
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class, 'GROUP_ID', 'ROLE_ID');
}
}
And this is group_role table model. It handles many to many relation between role and group:
class GroupRole extends Model
{
protected $table = 'group_role';
protected $primaryKey = 'GROUP_ROLE_ID';
protected $fillable = [
'COMMENT', 'ROLE_ID', 'GROUP_ID'
];
public $timestamps = false;
}
Problem begin when i want to use this models. For example:
$role = App\Role::first();
$groups = $role->groups;
Laravel returns this error messages:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'favian_mydb.App\GroupRole' doesn't exist (SQL: select groups.*, App\GroupRole.ROLE_ID as pivot_ROLE_ID, App\GroupRole.GROUP_ID as pivot_GROUP_ID from groups inner join App\GroupRole on groups.GROUP_ID = App\GroupRole.GROUP_ID where App\GroupRole.ROLE_ID = 1)
I tried to replace App\GroupRole with group_role and executing in mysql. It works fine. Am i missing something?
The Problem is in your roles relation:
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class,'GROUP_ID','ROLE_ID');
}
The belongsToMany expects the intermediate table name as second argument, not the class name.
So you have to define it like this:
public function roles()
{
return $this->belongsToMany(Role::class, 'group_role','GROUP_ID','ROLE_ID');
}
I think the problem is in you relation functions. Try to use strings instead of Model::class.
Example:
return $this->return $this->belongsTo('App\GroupType', 'TYPE', 'TYPE_ID');
Hope this works.

Resources