Save Eloquent model with relation make two entries, why? - laravel

This is my controller method:
public function store(Request $request, $course_id){
$price['value'] = $request->price;
$price['desc'] = $request->desc;
If ($request->promo === "on") {
$price['promo'] = 1;
} else {
$price['promo'] = 0;
}
$course = Course::find($course_id);
Price::create($price)->courses()->save($course);
return redirect('/course/'.$course_id.'/edit');
}
For example if my request var have:
$request->price = 100
$request->desc = 'blablabla'
$request->promo = 'on'
After I submit the form I got two new rows with the same data:
Table prices:
id | price | desc | promo
1 | 100 | blablabla | on
2 | 100 | blablabla | on
Some info on models, I've:
public function courses () {
return $this->belongsToMany('App\Course', 'course_price');
}
in prices model and:
public function prices () {
return $this->belongsToMany('App\Price', 'course_price');
}
in courses model.
Whats wrong?

Try attach:
$price = Price::create($price);
$price->courses()->attach($course_id);
instead of:
$course = Course::find($course_id);
Price::create($price)->courses()->save($course);

it's looks like you make double post request on
Price::create($price)->courses()->save($course);
create and save.
please try your code with
Price::create($price)->courses();

Related

Laravel - how to reach model function with API

Trying to reach my model atrributes with api response.
Here's my Customer.php (model)
class Customer extends Model
{
public function debt()
{
if($this->company_id){
if($this->company->is_fleet){
$total = $this->company->fleetOrders->where('status', 1)->sum(function($t){
return $t->total - $t->discount + $t->vat;
});
$receipts = $this->company->allReceipts->whereNull('fleet_id')->sum('price');
return money_formatter($total-$receipts);
}
$vehicles = $this->company->vehicles->whereNotNull('fleet_id')->pluck('id')->toArray();
$total = $this->company->orders->whereNotIn('vehicle_id', $vehicles)->where('status', 1)->sum(function($t){
return $t->total - $t->discount + $t->vat;
});
$receipts = $this->company->allReceipts->whereNull('fleet_id')->sum('price');
return money_formatter($total-$receipts);
}
$vehicles = $this->customerVehicles->whereNotNull('fleet_id')->pluck('id')->toArray();
$total = $this->customerOrders->where('status', 1)->whereNotIn('vehicle_id', $vehicles)->sum(function($t){
return $t->total - $t->discount + $t->vat;
});
$receipts = $this->customerReceipts->whereNull('fleet_id')->sum('price');
return money_formatter($total-$receipts);
}
}
And here's what I'm trying to make.
I need to reach my "debt" function from other relation. But couldnt make it in health.
public function index()
{
$d = $this->request->all();
$parameters = $this->request->query();
$firm_id = $this->request->user()->firm_id;
$user = $this->request->user();
$tires = Order::where('firm_id', $firm_id)
->with('customer', 'customer.debt')->get()
....
You don't need customer.debt as it's not a relation actually. This method is available on customer already.
While you are looping through $tires you can access that method by $tire->customer->debt()
You can not just pass this like relation I guess. You have to prepare that data in controller or Resource Collection.

Count the number of posts for logged in user in laravel

I want a number of posts that logged in user to have
I tried but I don't know how it will work
public function limitation()
{
$limit = 3;
$ads = User::WithCount('ads')->get();
}
Any help will appericiate
it works!!
$limit = 3;
$userId = auth()->user()->id;
$userPostCountId = User::where('id', $userId);
$posts=User::withCount('ads')->first(); //Suggest:- it will return post counts
along with user details
if ($userId>0) {
# code...
if(isset($posts->ads))
{
$count = sizeof($posts->ads);
if ($count>=$limit) {
return redirect()->route('ad.index');
}
}
If you have set up your user-posts relationship correctly like so:
class User {
public function posts(){
return $this->hasMany('App\Posts')
}
}
then you can get the users posts like so
$user = Auth::user();
$numPosts = $user->posts()->count();
Read more about relationships and how to query them here: https://laravel.com/docs/6.x/eloquent-relationships#one-to-many
Make sure you defined proper model naming
Also, you have to define a relationship between users and posts
User Model
public function posts()
{
return $this->hasMany(Posts::class);
}
In your controller
public function userPosts()
{
$userId = auth()->user()->id;
$userPostCount = User::where('id', $userId)->withCount('posts')->first(); //Suggest:- it will return post counts along with user details
//or auth()->user()->posts()->count() //it will return only post count
// or if you want to count with post also
// $userPosts = User::where('id', $userId)->with('posts')->withCount('posts')->first(); // it will return user posts and post counts along with user data
return $userPostCount; // or $userPosts
}
For more information please read: Laravel eloquent relationship
use skip and take functions
$limit = 3;
$ads = User::WithCount('ads')->skip(0)->take($limit)->get();

laravel many to many with chaining where clause

I have a given table :
tools toolparts parts part_details
----- --------- ----- ------------
id* id* id* id*
name tool_id name part_id
part_id total (int)
----- --------- ----- ------------
the relation between Tools and Parts is ManyToMany. and the relation between parts and part_details is one to many.
with Laravel model, how can I get tool with part that has the biggest part_details.total ??
//tool model
public function parts()
{
return $this->belongsToMany('App\Part', 'tool_part');
}
//part model
public function tools()
{
return $this->belongsToMany('App\Tool', 'tool_part')
}
public function details(){
return $this->hasMany('App\Part_detail');
}
//partDetail model
public function part(){
return $this->belongsTo('App\Part');
}
Controller
public function index()
{
$tools = Tool::with('parts', 'parts.details')->has('parts')->get();
return $tools;
}
what I expected is something like :
Controller
public function index()
{
$tool = Tool::with('SinglePartThatHasHigestTotalInPartDetail');
}
Any Idea ??
You can use Laravel aggregates for querying to get the desired result,
In your code use max() function,
public function index()
{
$tool = Tool::with(['parts.part_details' => function ($query) {
$max = $query->max('total');
$query->where('total',$max);
})->first();
}
I haven't tested this but you can do like this.
Comment if you will get any errors.
I Manage my problem with "hacky" ways. if someone have a better and more elegant solution, please tell me.
//tool model
public function partWithHighestTotalDelivery($trans_date = null){
if (is_null($trans_date)) {
$trans_date = date('Y-m-d');
}
$parts = $this->parts;
$highest_total_delivery = 0;
foreach ($parts as $key => $part) {
$part->detail;
$total_delivery = $part->first_value;
if (isset( $part->detail->total_delivery )) {
$total_delivery += $part->detail->total_delivery;
}
if ($highest_total_delivery < $total_delivery ) {
$highest_total_delivery = $total_delivery;
$part->total_delivery = $highest_total_delivery;
$result = $part;
}
}
if (!isset($result)) {
$result = null;
}
$this->part = $result;
}
In controller i have :
public function index(Request $request){
$tools = Tool::has('parts')
->get();
$tools->each(function($tool){
$tool->partWithHighestTotalDelivery();
});
return $tools;
}
with this, I need to run tool->partWithHighestTotalDelivery() tools.count times. which is take noticeable process if the tools is many.
and also, the code I post and the question I ask has a slightly difference.that's for a simplicity sake's
Use the the hasManyThrough Relationship to get the all part details related to tool and then you can check the one by one record and get the highest total of the tool part.
// Tool Model
public function partsdetails()
{
return $this->hasManyThrough('App\PartDetail', 'App\Part','tool_id','part_id');
}
In Your controller
$data = Tool::all();
$array = [];
if(isset($data) && !empty($data)) {
foreach ($data as $key => $value) {
$array[$value->id] = Tool::find($value->id)->partsdetails()->max('total');
}
}
if(is_array($array) && !empty($array)) {
$maxs = array_keys($array, max($array));
print_r($maxs);// This array return the max total of the tool related parts
}
else{
echo "No Data Available";
}
You can start with the part detail and get the tool(s) from there:
$maxPartDetail = Part_detail::orderByDesc('total')->first();
$tools = $maxPartDetail->part->tools;

Fetch specific gender in Codeigniter using mysql Database

Hello guys i am developing matrimony web application my problem is i have database field gender. if user is logged in then check the user gender if user is male then fetch all the female from database and if user is female then fetch all the male.
controller
public function profile() {
$this->load->view('header');
$uname = $this->session->userdata('logged_in');
if ($uname['gender'] == 'male')
{
// $this->model_name->get_male();
echo 'male';
}
// $this->model_name->get_female();
else
{
echo 'female';
}
}
updated code but it's fail condition every time . i have compare session user name to check user is male or female but it fail
This is model
class brid_groom_fetch extends CI_Model {
function get_program_specific_gender() {
$result = $this->db->get('bride_groom_register');
return $result->result_array();
}
First thing is you need to check the user currently logged in gender.
Example:
if($user['gender'] == 'male'){
//run get male gender from database
$this->model_name->get_male();
} esle {
$this->model_name->get_female();
}
Model:
class brid_groom_fetch extends CI_Model {
function get_male() {
$result = $this->db->get('bride_groom_register');
$this->db->where('gender' = 'male');
return $result->result_array();
}
function get_female() {
$result = $this->db->get('bride_groom_register');
$this->db->where('gender' = 'female');
return $result->result_array();
}
}
Note: This is just an example to give you an idea. Hope this could help.

Share value from database in all view in laravel 5

I'm new to laravel. I'm trying to create a simple app with some variable that shouold be in every view. So I create a setting model, with many fields and a unique slug field. Now to share this variable from database I've created a middleware:
public function handle($request, Closure $next)
{
$site_settings = Cache::remember('settings', 60, function() {
return Setting::all();
});
view()->share('site_settings', $site_settings);
return $next($request);
}
Now to show this variable in view I have:
{{{ $site_settings->get(0)->value }}}
This works great, but I'd like to have a more intuitive code in my view, accessing the setting by slug. Something like:
{{{ $site_settings->findBySlug("MYVARIABLE")->value }}}
So it's possible to filter collection by an unique slug?
Info:
This assumes your settings table structure is as following:
----------------------
| id | key | value |
----------------------
| 1 | titleĀ | foo |
| 2 | asd | bar |
| 3 | qqq | zzz |
----------------------
Steps
Step 1: Put the following newCollection method into App\Setting model:
class Settings extends ... {
public function newCollection(array $models = array())
{
return new \App\Collections\SettingsCollection($models);
}
}
Step 2: Put the following lines into App\Collections\SettingsCollection class:
<?php namespace App\Collections;
use Illuminate\Database\Eloquent\Collection;
class SettingsCollection extends Collection {
public function get($name, $default = null)
{
return array_first($this->items, function($itemKey, $model) use ($name)
{
return $model->key == $name;
}, $default)->value;
}
}
Step 3: Enjoy! This is the collection I'm currently using. Instead of this:
$settings = Setting::all();
$settings->where('key', 'key_name')->first()->value;
You can simply just do this:
$settings = Setting::all();
echo $settings->get('key_name'); // returns value of the setting with the key 'title'
Maybe a query scope would fit.
In your model:
public function scopeFindBySlug($slug){
return $query->where('slug','=', $slug);
}
So you will have: $site_settings->findBySlug('your_slug')->get();

Resources