I have 3 tables like this
Student:
id | name
class Student extends Model
{
protected $table = 'students';
public function marks () {
return $this->belongsToMany( 'App\Models\Subject', 'marks' )->using( 'App\Models\Mark');
}
}
Subject:
id | name
class Subject extends Model
{
protected $table = 'subjects';
public function marks () {
return $this->belongsToMany( 'App\Models\Student', 'marks' )->using( 'App\Models\Mark');
}
}
Mark:
subject_id | student_id | type_of_exam | times_taking_exam | mark
class Mark extends Pivot
{
protected $table = 'marks';
public function student() {
return $this->belongsTo('App\Models\Student','student_id');
}
public function subject() {
return $this->belongsTo('App\Models\Student','subject_id');
}
public $timestamps = false;
}
The table Mark which has 4 column primary key (id_subject, id_student, type_of_exam, times_taking_exam)
I don't know my design database is correct or not, but if it did, how can I use sync to update or insert mark for my student.
Because I understand that the method sync is like this:
$student->marks()->sync([
$subject_id => [
'type_of_exam' => 1,
'times_taking_exam' => 1,
'mark' => 10,
]
]);
But it is not correct for this situation cause it will run this code like this:
Mark::updateOrCreate( [
'student_id' => $student_id,
'subject_id' => $subject_id,
], [
'type_of_exam' => 1,
'times_taking_exam' => 1,
'mark' => 10
] );
Instead, I want this:
Mark::updateOrCreate( [
'student_id' => $student_id,
'subject_id' => $subject_id,
'type_of_exam' => 1,
'times_taking_exam' => 1,
], [
'mark' => 10
] );
I have tried use Mark as Model but I think it's not the best way.
Related
I have a table that contains foreign keys of product properties and their values.
product_id
feature_id
value_id
1
1
2
1
1
3
1
2
4
How to get a collection of that values using Eloquent?
Something like this
product => [
id => 1,
...
features => Collection: [
Feature: [
id => 1,
name => Size,
values => [
Value: [
id => 2,
name => M
],
Value: [
id: 3,
name: L
]
]
],
Feature: [
id => 2,
name => Color,
values => [
Value: [
id => 4,
name => Red
]
]
]
]
]
This is my solution.
class Product extends Model
{
protected $appends = ['features'];
protected array $features;
protected bool $featuresAppend = false;
public function getFeaturesAttribute(): Collection
{
if ($this->featuresAppend === false) {
$this->appendFeatures();
}
return collect($this->features);
}
public function productFeatures(): BelongsToMany
{
return $this->belongsToMany(Feature::class, 'product_features');
}
public function productFeatureValues(): BelongsToMany
{
return $this->belongsToMany(
FeatureValue::class,
'product_features',
'product_id',
'value_id'
);
}
protected function appendFeatures(): void
{
// Get futures and values by relationships
$features = $this->productFeatures()->get()->keyBy('id');
$values = $this->productFeatureValues()->get()->keyBy('id');
// Create features-values structure
$features->each(
function ($f) {
$this->features[$f->id] = new \StdClass();
$this->features[$f->id]->feature = $f;
}
);
// Appends values to future
$values->each(
function ($v) {
if (array_key_exists($v->feature_id, $this->features)) {
$this->features[$v->feature_id]->values[$v->id] = $v;
}
}
);
$this->featuresAppend = true;
}
}
I'm looking for a better solution to this problem or a solution using native Laravel features.
I trying to export a Excel file, from a collection using laravel. The code bellow, returns me this. I need to add a 2 new rows above the start of columsn, is that possible? What Should I do?
<?php
namespace App\Traits;
namespace App\Exports;
// use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Collection;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithColumnWidths;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
class exportSafety implements FromCollection, WithHeadings, WithMapping, WithColumnWidths, WithStyles, WithColumnFormatting, WithCustomStartCell
{
protected $services;
protected $request;
public function __construct(Collection $services)
{
$this->services = $services;
}
public function startCell(): string
{
return 'A3';
}
public function columnWidths(): array
{
return [
'A' => 30,
'B' => 20,
'C' => 20,
'D' => 15,
];
}
public function columnFormats(): array
{
return [
'B' => NumberFormat::FORMAT_DATE_DDMMYYYY,
];
}
public function styles(Worksheet $sheet)
{
return [
// Style the first row as bold text.
3 => ['font' => ['bold' => true]],
];
}
public function collection()
{
$this->services->each(function ($service) {
$this->map($service);
});
return $this->services;
}
public function headings(): array
{
$columns = [
'Name' => 'Name',
'Data de Nascimento' => 'Data de Nascimento',
'CPF' => 'CPF',
'Valor do Seguro' => "Valor do Seguro"
];
return $columns;
}
public function startRow(): int
{
return 2;
}
public function map($service): array
{
$columns = [
'Name' => $service->name,
'Data de Nascimento' => $service->birthdate,
'CPF' => $service->cpf,
'Valor do Seguro' => $service->client->donation_safety
];
return $columns;
}
}
But I need something like this:
I need to put two custom row above the start of the columns, is that possible? How I to that? I am using https://docs.laravel-excel.com/3.1/imports/multiple-sheets.html
you need to use WithHeadings trait to format heading rows.
$rangeHeadings = [
'chiqaruvchi',
'chiqarilgan',
'sotilgan',
"sana",
];
public function headings(): array
{
return [
[
$this->product?->name . " product " . $this->params['from_date'] . ' - ' . $this->params['to_date'] . " report",
],
$rangeHeadings,
];
}
I have a problem getting media from a joined table in laravel-medailibrary, I used getFirstMediaUrl("images") to get photos from one table and it works, but if I join two or three tables it not work, how can I solve it?
I want to get photos from those posts that shared by a user.
this post table:
this is share_tb table:
this is users table:
this is the media table:
I find my answer after trying some ways:
public function getPosts(Request $request)
{
$result = [];
$postID = DB::table("share_tb")->where("user_id", Auth::user()->id)->get();
foreach ($postID as $id) {
if (count(Post::where("id", $id->related_id)->get()) > 0) {
$posts = Post::where("id", $id->related_id)->get();
foreach ($posts as $post) {
// $result = $post->getMedia('images');
array_push($result, [
"comment_count" => getTotalComment($post->id),
"course_id" => $post->course_id,
"id" => $post->id,
'post_image' => count($post->getMedia('images')) > 0 ? $post->getMedia('images')[0]->getFullUrl('big') : "",
'logo'=>GetCourseLogo::collection(Course::where('course_id',$post->course_id)->get()),
"post_author" => $post->post_author,
"post_date" => $post->post_date,
"post_excerpt" => $post->post_excerpt,
"post_modified" => $post->post_modified,
"post_parent" => $post->post_parent,
"post_title" => $post->post_title,
"post_type" => $post->post_type,
]);
}
}
}
return Response()->json($result);
}
and by this resource collection, I get the logo:
class GetCourseLogo extends JsonResource
{
public function toArray($request)
{
return $this->getFirstMediaUrl('logo');
}
}
I have no table in my database in this name (location_id) but it gives me the error.
"message": "SQLSTATE[42S02]: Base table or view not found: 1146 Table
'pht.location_id' doesn't exist (SQL: select locations.*,
location_id.location_trails_id as pivot_location_trails_id,
location_id.location_id as pivot_location_id from locations
inner join location_id on locations.id =
location_id.location_id where location_id.location_trails_id
in (11, 13, 15, 16, 121, 123, 124, 181))",
I cannot find how to resolve it. Please Help me To resolve this issue. Thanks In advance.
Here is the code of my controller.
public function get($id)
{
$locations = LocationTrails::whereTrailId($id)->with('locations')->orderBy('ordered','ASC')->get();
dd($locations);
// $locations = Trail::findOrFail($id)->locations()->paginate($this->perPage);
// dd($locations);
$tdata = [];
foreach($locations->items() as $location) {
$hints = $location->hints;
$hintsData = [];
foreach($hints as $hint) {
$hintsData[] = [
'title' => $hint->title,
'hint_text' => $hint->hint_text,
'hint_solution_text' => $hint->hint_solution_text,
'hint_image_path' => $hint->hint_image_path,
'hint_video_path' => $hint->hint_video_path,
'complexity_order' => $hint->complexity_order
];
}
$tdata[] = [
'id' => $location->id,
'title' => $location->title,
'radius' => $location->radius,
'latitude' => $location->latitude,
'longitude' => $location->longitude,
'rewards_points' => $location->rewards_points,
'location_info_link' => $location->location_info_link,
'hints' => $hintsData
];
}
$data = [];
$data['data'] = $tdata;
$data['meta']['paginator'] = $this->getPaginatorInfo($locations);
return $data;
}
Here is my model of location
class Location extends Model
{
protected $table = 'locations';
protected $fillable = [
'title', 'radius', 'latitude', 'longitude', 'rewards_points', 'location_info_link', 'location_order'
];
/********************* RELATIONS *********************/
public function trails()
{
return $this->belongsToMany(Trail::class);
}
public function hints()
{
return $this->hasMany(LocationHint::class);
}
public function location_trails()
{
return $this->belongsTo(LocationTrails::class,'location_id');
}
Here is my locationtrail model:
class LocationTrails extends Model
{
protected $table = 'location_trail';
protected $fillable = [
'location_id', 'trail_id', 'ordered', 'created_at', 'updated_at',
];
/********************* RELATIONS *********************/
public function trails()
{
return $this->belongsToMany(Trail::class,'trail_id');
}
public function locations()
{
return $this->belongsToMany(Location::class,'location_id');
}
problem is in your LocationTrails model. You define your method like $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id'); so, laravel think location_id is a table name and the error thrown.
If it is one to many relationship.
public function locations()
{
return $this->hasMany(Location::class,'location_id');
}
If it is many to many relationship then you can see this.
https://laravel.com/docs/5.8/eloquent-relationships#many-to-many
same for your trails() method.
public function trails()
{
return $this->hasMany(Trail::class,'trail_id');
}
Model relation
---------------------
language.php
----
public function attributeDetail()
{
return $this->hasMany(AttributeDetail::class, 'language_id');
}
attribute.php
----
public function attributeDetail()
{
return $this->hasMany(AttributeDetail::class, 'attribute_id');
}
attributeDetail.php
----
public function language()
{
return $this->belongsTo(Language::class);
}
public function attribute()
{
return $this->belongsTo(Attribute::class);
}
I want to show the json object like this
{
'attribute_id' => 101,
'available_language' => [
{'id' => 1,'language_name' => 'English'},
{'id' => 2,'language_name' => 'French'}
],
}
table structure:
languages(`id`, `language_name`, `translate_version`, `is_default`, `status`);
attributes(`id`, `required`, `type`, `status`);
attributedetails(id`, `attribute_id`, `language_id`, `attribute_name`, `status`);
Try somthing like this,
$results = Attribute::select('id')->with(['attributeDetail.language' => function ($query) {
$query->select('id', 'language_name');
}])->get();