I have 4 tables Users, Regions, Rentals, and Locations
- Each User hasMany Rentals
- Each Region hasMany Rentals
- Each Location hasMany Rentals
- Basically a Rental belongsTo all 3 tables
Region - id, name Location - id, street_address, city, province, postal_code Rental - id, region_id, location_id, user_id
I've set up the hasMany and belongsTo relationships between these tables and tested them in Tinker, but now I want to create and update rentals.
- The region_id is passed up through the request - $regionId
- The user_id is the Auth::id() - $userId
- The location_id is found by taking only() part of the request and doing a check of the locations table, and if it exists I grab the location_id - $locationId
- The remaining post data is grabbed using only() again for that data - $rentalData
All this works to this point, but how do you create and update rentals using the ids and data I've extracted, this almost works:
Location::find($locationId)->rentals()->create($rentalData);
But, need to get the $locationId and $userId into the mix somehow and it doesn't seem right to make them fillable.
I've been playing with it like this so far:
// Retrieve the chosen rental region
$regionId = Region::find($request->input('region_id'));
// Retrieve authenticated user id
$userId = Auth::id();
// Retrieve rental location data
$rentalLocationData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
// Does the location already exist? If not create and persist it to the database
$locationData = RentalLocation::firstOrCreate($rentalLocationData);
$locationId = $locationData->id;
// Create the rental...?
$rental = Location::find($locationId)->rentals()->create($rentalData);
UPDATE
So I can keep going dropped using the ORM and did this, but I'd still like to understand how Eloquent works beyond the basics I learnt watching Laracast videos so any help would be appreciated, right now I just find it really confusing:
// Retrieve rental location data from the request
$requestData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
// Does the location already exist? If not create and persist it to the database
$rentalLocation = RentalLocation::firstOrCreate($requestData);
// Retrieve the foreign key ids not included in request
$foreignKeyIds = [ 'user_id' => Auth::id(), 'rental_location_id' => $rentalLocation->id ];
// Retrieve request data for creating a rental, and merge with foreign key ids
$requestData = $request->only('region_id', 'stall', 'level', 'description');
$rentalData = array_merge($foreignKeyIds, $requestData);
// Insert new rental with all field attributes included
DB::table('rentals')->insert($rentalData);
UPDATE
What about this solutions?
RentalRequest checks the region_id exists, and the user will always be the Auth::user().
public function store(RentalRequest $request)
{
// Retrieve the authenticated user
$User = Auth::user();
// Retrieve rental location data from request
$requestData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
// Does the location already exist? If not create and persist it to the database
$RentalLocation = RentalLocation::firstOrCreate($requestData);
// Retrieve the region for inserting the rental
$Region = Region::find($request->input('region_id'));
// Retrieve rental data from request
$requestData = $request->only('stall', 'level', 'description');
// Create a new rental, fill with request data, and add relationships
$rental = new Rental;
$rental->fill($requestData);
$rental->owner()->associate($User);
$rental->location()->associate($RentalLocation);
// Persist rental to database
$rental = $Region->rentals()->save($rental);
// Return rental data for capture by AngularJS interceptor
// TODO: filter rental data don't need it all returned to client
return response()->json([
'rental' => $rental,
'action' => 'rental_registered',
'message' => trans('rental.registered')
]);
}
I don't understand why to make it so complex?
try this:
Solution 1
Solution 2