I am trying to attach documents to a model when saving. I am getting array to string conversion erro. Because, it puts the documents Ids in to an array.
Here is my model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Orchid\Screen\AsSource;
use App\Models\Seller;
use Orchid\Attachment\Models\Attachment;
use Orchid\Attachment\Attachable;
use Orchid\Filters\Filterable;
use Orchid\Metrics\Chartable;
use App\Orchid\Presenters\PropertyPresenter;
use Laravel\Scout\Searchable;
class Property extends Model
{
use HasFactory;
use AsSource, Attachable,Filterable;
use Chartable;
/**
* #var array
*/
protected $fillable = [
'property_name',
'property_type',
'property_city',
'property_address',
'property_area',
'seller_id',
'property_cost',
'property_price',
'property_rent_price',
'status',
'contracts',
'images'
];
/**
* Get the parent seller of the property.
*/
public function seller()
{
return $this->belongsTo(Seller::class);
}
/**
* Name of columns to which http sorting can be applied
*
* #var array
*/
protected $allowedSorts = [
'property_name',
'property_type',
'property_city',
'status',
'created_at',
'updated_at'
];
/**
* #param Builder $query
*
* #return Builder
*/
public function scopeActive(Builder $query)
{
return $query->where('status', 'Available');
}
/**
* #param Builder $query
*
* #return Builder
*/
public function scopeStatus(Builder $query)
{
return $query->where('status', '!=', 'Sold');
}
// Many-to-Many (no foreign id on table, should be uploaded with groups() function)
public function documents()
{
return $this->hasMany(Attachment::class)->where('group','contracts');
}
/**
* Get the presenter for the model.
*
* #return PropertyPresenter
*/
public function presenter()
{
return new PropertyPresenter($this);
}
/**
* Get the indexable data array for the model.
*
* #return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// Customize array...
return $array;
}
}
Here are the form elements
Upload::make('property.contracts')
->title('Documents')
->maxFileSize(2)
->targetId()
->targetRelativeUrl()
->groups('documents')
->acceptedFiles('image/*,application/pdf,.psd'),
And here is the save/update function
/**
* #param Property $property
* #param Request $request
*
* #return \Illuminate\Http\RedirectResponse
*/
public function createOrUpdate(Property $property, Request $request)
{
$property->fill($request->get('property'))->save();
$property->attachment()->syncWithoutDetaching(
$request->input('property.contracts', [])
);
Alert::info('You have successfully created an property.');
return redirect()->route('platform.property.list');
}
Finally here is the migration file
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('properties', function (Blueprint $table) {
$table->id();
$table->string('property_name');
$table->string('property_type');
$table->string('property_city');
$table->text('property_address');
$table->double('property_area',15,2);
$table->unsignedBigInteger('seller_id');
$table->double('property_cost', 20.3);
$table->double('property_price');
$table->double('property_rent_price')->nullable();
$table->string('contracts')->nullable();
$table->string('images')->nullable();
$table->string('status')->default('Available');
$table->timestamps();
$table->foreign('seller_id')->references('id')->on('sellers');
});
}
It gives the array to string conversion error and here is the request body:
{ "property_name": "Villa02", "property_type": "residential", "property_city": "Garoowe", "property_address": "Test", "property_area": "12000", "seller_id": "1", "property_cost": "43000", "property_price": "50000", "property_rent_price": "300", "status": "Available", "contracts": [ "67" ], "images": "/storage/2022/04/15/e3cbed3acbfec1d40c54aa57aa651a05c80d6586.png" }
Thanks in advance.
Just unset the array before filling the model
public function createOrUpdate(Property $property, Request $request)
{
$propertyInputs = $request->get('property');
$contacts = $propertyInputs['contracts']??[];
unset($propertyInputs['contracts']);
$property->fill($propertyInputs)->save();
$property->attachment()->syncWithoutDetaching($contacts);
Alert::info('You have successfully created an property.');
return redirect()->route('platform.property.list');
}
Related
I am trying to develop an app for schools and parents where the class teachers will be able to upload pictures of a student when a student check-in to school and check-out from school. This app will have a backend which will be built using laravel 9. The whole app is based on API.
Image of App User Interface here
I want to show photos of check-in and check-out side by side based on the date. If check-out is not updated yet, then the check-in image will be there and the check-out section will be empty.
Here is the JSON response that I am working with:
{
"data": [
{
"id": 1,
"child_id": 1,
"date": "18-08-2022",
"time": "08:49:51",
"status": "check_in",
"image": "https://via.placeholder.com/640x480.png/008833?text=kids+et"
},
{
"id": 6,
"child_id": 1,
"date": "18-08-2022",
"time": "10:24:38",
"status": "check_out",
"image": "https://via.placeholder.com/640x480.png/00ffdd?text=kids+veritatis"
}
]
}
Laravel Controller:
<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreCheckInOutRequest;
use App\Http\Requests\UpdateCheckInOutRequest;
use App\Http\Resources\V1\CheckInOut\CheckInOutResource;
use App\Models\CheckInOut;
use App\Services\V1\CheckInOutQuery;
use Illuminate\Http\Request;
class CheckInOutController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$filter = new CheckInOutQuery();
$queryItems = $filter->transform($request); //[['column', 'operator', 'value']]
if (count($queryItems) == 0) {
return response()->json(['message' => 'No child id provided'], 400);
} else {
return CheckInOutResource::collection(CheckInOut::where($queryItems)->orderBy('date', 'desc')->get());
}
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(StoreCheckInOutRequest $request)
{
$checkInOut = CheckInOut::create($request->all());
return response()->json(['message' => 'Check in & out status created successfully.', 'data' => $checkInOut], 201);
}
/**
* Display the specified resource.
*
* #param \App\Models\CheckInOut $checkInOut
* #return \Illuminate\Http\Response
*/
public function show(CheckInOut $checkInOut)
{
return new CheckInOutResource($checkInOut);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Models\CheckInOut $checkInOut
* #return \Illuminate\Http\Response
*/
public function update(UpdateCheckInOutRequest $request, CheckInOut $checkInOut)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param \App\Models\CheckInOut $checkInOut
* #return \Illuminate\Http\Response
*/
public function destroy(CheckInOut $checkInOut)
{
//
}
}
Laravel API Resource:
<?php
namespace App\Http\Resources\V1\CheckInOut;
use Illuminate\Http\Resources\Json\JsonResource;
class CheckInOutResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'child_id' => $this->child_id,
'date' => date('d-m-Y', strtotime($this->date)),
'time' => $this->time,
'status' => $this->status,
'image' => $this->image
];
}
}
Database Migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('check_in_outs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('child_id');
$table->date('date');
$table->time('time');
$table->string('status')->comment('check_in, check_out');
$table->string('image')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('check_in_outs');
}
};
CheckInOut Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CheckInOut extends Model
{
use HasFactory;
protected $fillable = [
'child_id',
'date',
'time',
'status',
'image'
];
protected $hidden = [
'created_at',
'updated_at'
];
public function child()
{
return $this->belongsTo(Child::class);
}
}
Please help me, how can I design my API response and handle the API response to achieve my goal of design in flutter? Image of App User Interface here
The backend information is irrelevant, we only have to take into account the response in json
Create a model of your response. (You can use https://quicktype.io/ and paste your json output to get the Model class in Dart, the class you will get already has methods to map the objects from json.)
The design is not difficult, you should visit https://docs.flutter.dev/development/ui/widgets/material.
API requests can be done with https://pub.dev/packages/http and you can show images with https://docs.flutter.dev/cookbook/images/network-image
. Hope it helps your asking for a lot of information.
I am using Laravel 8 and I was wondering if there is anyway to automatically delete original image after it has converted in Spatie Media Library? it's currently taking up my storage space so I want to be able to delete original images.
here's the model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\Models\Media;
class Profile extends Model implements HasMedia
{
use HasMediaTrait, softDeletes;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'user_id',
'theme_id',
'name',
'username',
'location',
'bio',
'views',
];
protected $appends = [
'avatar_url',
'route',
];
protected $with = [
'links',
'theme',
];
/**
* Get the route key for the model.
*
* #return string
*/
public function getRouteKeyName()
{
return 'username';
}
/**
* #return mixed
*/
public function getAvatarUrlAttribute()
{
if ($this->hasMedia('avatar')) {
return $this->getFirstMedia('avatar')->getUrl('cropped');
}
return asset('/images/avatar.png');
}
/**
* #return mixed
*/
public function getRouteAttribute()
{
return route('profiles.show', $this);
}
/**
* #return mixed
*/
public function getKeywordsAttribute()
{
$keywords = $this->links
->map(function ($link) {
return "{$link->name} {$this->name}";
})
->toArray();
$keywords[] = $this->name;
return implode(',', $keywords);
}
/**
* Get all of the profile's links.
*
* #param string $order
*
* #return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function links($order = 'asc')
{
return $this->morphMany(Link::class, 'linkable')->orderBy('order', $order);
}
/**
* Get profile theme.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function theme()
{
return $this->belongsTo(Theme::class);
}
/**
*
*/
public function viewed()
{
$this->increment('views');
}
/**
*
*/
public function registerMediaCollections()
{
$this->addMediaCollection('avatar')->singleFile();
}
/**
* #param Media|null $media
*
* #throws \Spatie\Image\Exceptions\InvalidManipulation
*/
public function registerMediaConversions(Media $media = null)
{
$this->addMediaConversion('cropped')
->crop(Manipulations::CROP_CENTER, 200, 200)
->nonQueued()
->performOnCollections('avatar');
}
}
Anyone know any method to do this so I can save storage space?
I can not delete a row using a simple eloquent query. Even when I am using eloquent can not get the data from DB. I am getting null. But, in DB query method at least I am getting data but can not delete then. Following is my code:
DB::transaction(function () use ($lead, $comment, $request) {
$lead->save();
$lead->comments()->save($comment);
if ($request->deleteAppointment) {
$calendarEvent = DB::table('calendar_events')->where('id', $request->appointmentId)->first(); // I am getting data here.
$calendarEvent = CalendarEvent::find($request->appointmentId); // But, here I am getting null, don't know why!
if ($calendarEvent != null) {
$calendarEvent->delete();
}
}
My goal is to get the data using Eloquent and then Delete from database.
update:
My Database Table
CalendarEvent.php model
class CalendarEvent extends Model
{
use SoftDeletes;
/**
* #var array
*/
protected $casts = [
'event_begin' => 'datetime',
'event_end' => 'datetime',
'options' => 'array',
];
/**
* #var array
*/
protected $guarded = [
'id',
];
/**
* #return mixed
*/
public function users()
{
return $this->morphedByMany(User::class, 'eventable');
}
/**
* #return mixed
*/
public function attendees()
{
return $this->morphedByMany(User::class, 'eventable')->withPivotValue('role', 'atendee');
}
/**
* #return mixed
*/
public function companies()
{
return $this->morphedByMany(Company::class, 'eventable')->withPivotValue('role', 'company');
}
/**
* #return mixed
*/
public function invitees()
{
return $this->morphedByMany(User::class, 'eventable')->withPivotValue('role', 'invitee');
}
/**
* #return mixed
*/
public function leads()
{
return $this->morphedByMany(Lead::class, 'eventable')->withPivotValue('role', 'lead');
}
}
Why not just:
CalendarEvent::where('id', $request->appointmentId)->delete();
Also, check the deleted_at column. If that is not null, then the select will return null, unless you add the ->withTrashed() method.
When using Eloquent objects, the SoftDelete trait is used, when using DB:: directly, then the SoftDelete trait is not used.
With some Models, when I make a new Nova Resource for them, seems that Nova can't find the Model because they doesn't show on sidebar (i can't reach them also by URL, giving me a 404).
But this happens only for specific Models and if I try to modify the target Model in the Resource with another one (editing the $model variable), it works and shows the Resource in the sidebar (but with the wrong model). Nova isn't throwing me any error so the debugging is getting crazy difficult.
The Models that doesn't work in my project are named "Product" and "Company".
I'm using Laravel 7.28.3, Nova 3.9.1, MariaDB 10.4.11 and PHP 7.4.1 with Homestead.
Here's the code of Product resource:
<?php
namespace App\Nova;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Http\Requests\NovaRequest;
class Product extends Resource
{
/**
* The model the resource corresponds to.
*
* #var string
*/
public static $model = \App\Product::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* #var string
*/
public static $title = 'title';
/**
* The columns that should be searched.
*
* #var array
*/
public static $search = [
'id', 'name'
];
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
];
}
/**
* Get the cards available for the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function actions(Request $request)
{
return [];
}
}
And here's the Model code:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Product extends Model implements HasMedia
{
use InteractsWithMedia;
public function visits()
{
return visits($this);
}
public function user() {
return $this->belongsTo('App\User');
}
public function company() {
return $this->belongsTo('App\Company');
}
public function productVariety() {
return $this->belongsTo('App\ProductVariety', 'product_variety_id');
}
public function productSpecies() {
return $this->belongsTo('App\ProductSpecies', 'product_species_id');
}
public function productNutrients() {
return $this->hasMany('App\ProductNutrient');
}
public function baseProduct() {
return $this->hasOne('App\Product', 'base_product_id');
}
public function recipes() {
return $this->hasMany('App\Recipe', 'base_product_id');
}
protected $fillable = [
'user_id', 'company_id', 'imageline_id', 'products_species_id', 'products_varieties_id', 'base_product_id',
'name', 'scientific_name', 'production_start', 'production_end', 'production_city', 'description', 'story', 'curiosities', 'advices', 'quantity_advices', 'why_good', 'who_good',
'is_base_product', 'show_related_recipes', 'show_related_products'
];
}
Check your AuthServiceProvider on app/Providers/AuthServiceProvider.php if there is a Policy set to this model. Then on your policy class (probably ProductPolicy which is bind to Product model, check view and viewAny methods, these methods must return true or conditional true.
I am trying to get the users (ID 1) trip data from the user_trips table, along with that trips flights in the user_flights table, and I am getting the airports.name using the flight_from and flight_to foreign keys.
I've tried numerous ways, and I assume it's very easy but this is my first Laravel project. I've read the documentation and watched LaraCasts but I just can't figure out the right combination.
The $user_flights variable returns:
[
{
"id":1,
"user_trips_id":6,
"flight_from":1,
"flight_to":14,
"flight from":
{
"id":1,
"code":"AIZ",
"name":"Lee C Fine Memorial",
"city":"Lake Of The Ozarks",
"country":"United States"
},
"flightto":
{
"id":14,
"code":"AEX",
"name":"Alexandria Intl Arpt",
"city":"Alexandria",
"country":"United States"
}
},
{
"id":2,
"user_trips_id":7,
"flight_from":1,
"flight_to":22,
"flight from":
{
"id":1,
"code":"AIZ",
"name":"Lee C Fine Memorial",
"city":"Lake Of The Ozarks",
"country":"United States"
},
"flightto":
{
"id":22,
"code":"ADG",
"name":"Lenawee County Arpt",
"city":"Adrian",
"country":"United States"
}
}
]
I need it to return something like this (I think):
[
{
"id":6,
"user_id":1,
"name":"My Trip",
"flights":
{
"id":1,
"user_trips_id":6,
"flight_from":1,
"flight_to":14,
"flight from":
{
"id":1,
"code":"AIZ",
"name":"Lee C Fine Memorial",
"city":"Lake Of The Ozarks",
"country":"United States"
},
"flightto":
{
"id":14,
"code":"AEX",
"name":"Alexandria Intl Arpt",
"city":"Alexandria",
"country":"United States"
}
}
}
]
Schema
# `user_trips` table
Schema::create('user_trips', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->text('name');
});
# `user_flights` table
Schema::create('user_flights', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_trips_id')->unsigned();
$table->integer('flight_from')->unsigned();
$table->integer('flight_to')->unsigned();
$table->foreign('user_trips_id')->references('id')->on('user_trips')->onDelete('cascade');
$table->foreign('flight_from')->references('id')->on('airports')->onDelete('cascade');
$table->foreign('flight_to')->references('id')->on('airports')->onDelete('cascade');
});
TripBuilderController
<?php
namespace App\Http\Controllers;
use App\Airport;
use App\UserFlights;
/**
* Class TripBuilderController
*
* #package App\Http\Controllers
*/
class TripBuilderController extends Controller
{
/**
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$airports=Airport::all();
# Returns all `user_trips` and `user_flights`.
# I need to return only `user_trips`.`user_id` associated to user ID 1,
# and the `user_flights` associated to the user's `user_trips`.
$user_flights=UserFlights::with('flightfrom')->with('flightto')->get();
return view('welcome', compact('airports', 'user_flights'));
}
}
UserTrips Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class UserTrips
*
*/
class UserTrips extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps=FALSE;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable=[
'name',
'user_id'
];
/**
* #param UserFlights $user_flights_obj
* #return Model
*/
public function addFlight(UserFlights $user_flights_obj)
{
return $this->userflights()->save($user_flights_obj);
}
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function userflights()
{
return $this->hasMany(UserFlights::class);
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
/**
* #return mixed
*/
public function addTrip()
{
# Retrieve the trip by the attributes, or instantiate a new instance...
$trip_obj=$this->firstOrNew(['user_id'=>1]);
if(!$trip_obj->id)
{
$trip_obj->name='My Trip';
$trip_obj->save();
}
return $trip_obj;
}
}
UserFlights Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class UserFlights
*
*/
class UserFlights extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps=FALSE;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable=[
'flight_from',
'flight_to'
];
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function flightfrom()
{
return $this->belongsTo(Airport::class, 'flight_from');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function flightto()
{
return $this->belongsTo(Airport::class, 'flight_to');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function usertrip()
{
return $this->belongsTo(UserTrips::class, 'user_trips_id');
}
}
User::find(1)->userTrips()->with('userflights', 'userflights.flightfrom', 'userflights.flightto')->get();
or calling directly from UserTrips
UserTrips::whereUserId(1)->with('userflights', 'userflights.flightfrom', 'userflights.flightto')->get();
with() gives you eager loading and when you convert a model a JSON, it includes any of the eager loaded models you specified.