Laravel MM sync throws Illuminate\Database\Eloquent\Relations\HasOne exception - laravel

I try to save many to many relations inside loop here is the code
$user = User::firstOrCreate(
[
'username' => $member->username,
'email' => $member->email
],
[
'password' => $member->password,
'name' => $member->fullname,
'email' => $member->email,
'firstname' => $member->firstname,
'lastname' => $member->lastname,
'username' => $member->username,
'active' => $member->active
]
);
if ($user) {
$user->account()->firstOrCreate([
'user_id' => $user->id,
],
[
'address' => $member->address,
'phone' => $member->phone,
'web' => $member->web,
'company' => $member->company,
'company_email' => $member->company_email,
'company_phone' => $member->company_phone,
'fax' => $member->fax,
'company_fax' => $member->company_fax,
'has_newsletter' => $member->newsletter,
'published' => $member->listing,
'zip' => $member->zip,
'association_id' => $member->association_id,
'affiliate_id' => $member->affiliate_id,
]);
if ($member->activity_group_ids) {
$user->account()->occupations()->snyc(explode(',',$member->activity_group_ids));
}
$user->assignRole('member');
}
but I keep getting Call to undefined method Illuminate\Database\Eloquent\Relations\HasOne::occupations()
my models:
User
/**
* #return HasOne
*/
public function account()
{
return $this->hasOne(Member::class);
}
Member
/**
* #return BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
/**
* #return BelongsToMany
*/
public function occupations()
{
return $this->belongsToMany(OccupationGroup::class, 'members_occupational_groups', 'member_id', 'occupation_group_id');
}
OccupationGroup
/**
* #return BelongsToMany
*/
public function members()
{
return $this->belongsToMany(Member::class, 'members_occupational_groups', 'occupation_group_id', 'member_id');
}
What is wrong in this case?

Related

Laravel Resource return value from another Resource?

I tried to find a solution here but nothing worked. I want to return values from TagResource using MealResource because I have TagTranslations table and I'm getting the data from the table with translations in TagResource.
Relationships are correctly formed, meal and tag models are connected via meal_tags table and tagtranslations belongsTo Tag::class.
I used TagResource like this:
class TagResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
$translation = $this->translations->where('tag_id', $this->id)->first();
return
[
'id' => $this->id,
'title' => $translation->title,
'slug' => $translation->slug,
];
}
}
and MealResource like this:
public function toArray($request)
{
$translation = $this->translations->where('meal_id', $this->id)->first();
$category_translation = $this->category->translations->where('category_id', $this->category->id)->first();
return [
'id' => $this->id,
'title' => $translation->title,
'decription' => $translation->description,
'category' => [
'id' => $this->category->id,
'title' => $category_translation->title,
'slug' => $category_translation->slug,
],
'tags' => FILL IN THE BLANK (have used TagResource:collection() and new TagResource()) and didnt work
];
}
public function toArray($request)
{
$translation = $this->translations->where('meal_id', $this->id)->first();
$category_translation = $this->category->translations->where('category_id', $this->category->id)->first();
return [
'id' => $this->id,
'title' => $translation->title,
'decription' => $translation->description,
'category' => [
'id' => $this->category->id,
'title' => $category_translation->title,
'slug' => $category_translation->slug,
],
'tags' => TagResource::collection($this->tags),
];
}
If all the Relationships namings/mappings are correct then this will work.And please make sure that model are perfectly mapped respectively.

Validation in Fast Excel package Laravel

ImportController
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Talent\ImportData\Requests\ImportDataRequest;
use Illuminate\Support\Facades\Hash;
use Rap2hpoutre\FastExcel\FastExcel;
class ImportController extends Controller
{
public function __construct(private User $user)
{
}
public function import(ImportDataRequest $request)
{
$validated = $request->validated();
$collection = (new FastExcel)->import($validated['file'], function ($rows) {
$user = $this->user->create([
'name' => $rows['First Name'] . " " . $rows['Last Name'],
'email' => $rows['Email'],
'password' => Hash::make('Introcept#123'),
'role' => $rows['Role']
]);
$employee = $user->employees()->create([
'status' => $rows['Status'],
'first_name' => $rows['First Name'],
'last_name' => $rows['Last Name'],
'email' => $rows['Email'],
'contact_number' => $rows['Contact Number'],
'date_of_birth' => $rows['Date of Birth'],
'current_address' => $rows['Current Address'],
'pan_number' => $rows['Pan Number'],
'bank_account_number' => $rows['Bank Account Number'],
]);
$education = $employee->education()->create([
'education_level' => $rows['Education Level'],
'passed_year' => $rows['Passed Year'],
'institution' => $rows['Institution'],
]);
$employment = $employee->employment()->create([
'organization' => $rows['Organization'],
'join_date' => $rows['Join Date'],
'current_position' => $rows['Current Position'],
'work_schedule' => $rows['Work Schedule'],
'team' => $rows['Team'],
'manager' => $rows['Manager'],
'superpowers' => $rows['Superpower'],
]);
$employment->manages()->create([
'employee_id' => $rows['Manages'],
]);
});
}
}
ImportData Request
<?php
namespace App\Talent\ImportData\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ImportDataRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array<string, mixed>
*/
public function rules()
{
return [
'file'=>'required|mimes:csv,xlsx'
];
}
}
I am creating an API where the admin can import data from an excel file. Here, I am using the Fast Excel package in order to import data. Everything is working fine, but I have no idea how I can validate excel data before saving it into the database. I am pretty new to Laravel and any help will be really appreciated. Thank you

Passing a new variable to Resource from Controller | Laravel

I have an API resources in my code,
what i wanted to do is to pass a new data to be return in Resource Collection
Controller:
public function index(Request $request)
{
// #TODO implement
$books = Book::with('authors')->paginate(5);
$pass = 1;
return BookResource::collection($books, $pass, 200);
}
my Resources:
public function toArray($request)
{
return [
// #TODO implement
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $this->pass
];
}
I want the $pass, can be returned in Resources,
how do i achieve that?
Try adding metadata to the collection using additional:
return BookResource::collection($books)->additional([
‘pass’ => $pass,
]);
BookResource
class BookResource extends Resource {
protected $pass;
public function pass($value){
$this->pass = $value;
return $this;
}
public function toArray($request){
return [
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $this->pass
];
}
public static function collection($resource){
return new BookResourceCollection($resource);
}
}
BookResourceCollection
class BookResourceCollection extends ResourceCollection {
protected $pass;
public function pass($value){
$this->pass = $value;
return $this;
}
public function toArray($request){
return $this->collection->map(function(BookResource $resource) use($request){
return $resource->pass($this->pass)->toArray($request);
})->all();
}
Pass params
BookResource::collection($books)->pass(1);
Or using this:
http://localhost:3000/api/books?pass=1
public function toArray($request) {
$pass = $request->pass;
return [
'id' => $this->id,
'isbn' => $this->isbn,
'title' => $this->title,
'description' => $this->description,
'published_year' => $this->published_year,
'authors' => AuthorResource::collection($this->authors),
'review' => BookReviewResource::collection($this->reviews),
'pass' => $pass
];
}

Laravel Resource is empty

I'm passing data to these functions via Axios/Vue. The Eloquent interactions work perfectly. When I store (i.e. create a new call) the resource returns as expected. When I update a record, it updates in the database, however, I get a blank response. In other words the return new CallResource($call) returns nothing. I can't work out where I've gone wrong.
public function store(Request $request)
{
$call = $this->validate($request, [
'title' => 'required',
'job_id' => 'required',
'location' => 'required',
'starts' => 'required|date|before:ends',
'ends' => 'required|date|after:starts',
'rate' => 'required'
]);
$call = Call::create($call);
return new CallResource($call);
}
public function update(Request $request, $id)
{
$data = $this->validate($request, [
'title' => 'required',
'job_id' => 'required',
'location' => 'required',
'starts' => 'required|date|before:ends',
'ends' => 'required|date|after:starts',
'rate' => 'required'
]);
$call = Call::find($id);
$call->update($data);
return new CallResource($call);
}
The call resource is really simple
class CallResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'location' => $this->location,
'starts' => $this->starts,
'ends' => $this->ends,
'rate' => $this->rate
];
}
}
Laravel 5.6 fyi.

Login when successfully updated the data of the user in Laravel

RegisterController.php
I added here an update function so that when the user wants to login with Facebook, he/she will be redirected to a form and then fill the fields so that their information will be stored in the Database.
protected function create(array $data)
{
if ($data['userEmail']) {
return User::where('email', $data['userEmail'])
->update([
'phone_number' => $data['phone_number'],
'address' => $data['address'],
'country' => $data['country'],
'city' => $data['city'],
'zip_code' => $data['zip_code'],
'state' => $data['state'],
'is_online' => true,
]);
} else {
return User::create([
'full_name' => $data['full_name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'phone_number' => $data['phone_number'],
'address' => $data['address'],
'country' => $data['country'],
'city' => $data['city'],
'zip_code' => $data['zip_code'],
'state' => $data['state'],
'is_online' => true,
]);
}
}
The error when the IF statement returns true is this
"Type error: Argument 1 passed to
Illuminate\Auth\SessionGuard::login() must implement interface
Illuminate\Contracts\Auth\Authenticatable, integer given, called in
C:\xampp\htdocs\esoftwaredeals\vendor\laravel\framework\src\Illuminate\Foundation\Auth\RegistersUsers.php
on line 35".
However, if it returns false, there will be no error and a new user is created and will automatically redirect to the "/my-account" page which is where I wanted to redirect when the user successfully updated their information.
You need to return User instance from the create() method:
protected function create(array $data)
{
if ($data['userEmail']) {
$user = User::where('email', $data['userEmail'])->first();
$user->update([
'phone_number' => $data['phone_number'],
'address' => $data['address'],
'country' => $data['country'],
'city' => $data['city'],
'zip_code' => $data['zip_code'],
'state' => $data['state'],
'is_online' => true,
]);
} else {
$user = User::create([
'full_name' => $data['full_name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'phone_number' => $data['phone_number'],
'address' => $data['address'],
'country' => $data['country'],
'city' => $data['city'],
'zip_code' => $data['zip_code'],
'state' => $data['state'],
'is_online' => true,
]);
}
return $user;
}
Also, you should use the updateOrCreate() method to keep the code maintainable. For example:
protected function create(array $data)
{
$data['password'] = bcrypt($data['password']);
return User::updateOrCreate(
array_only($data, ['email', 'full_name']),
array_except($data, ['email', 'full_name'])
);
}
An update query returns the number of rows that where affected by the update query.So when the update user is successful it will return 1.
The create method returns the saved model instance. So this is causing the issue in your code.
You can use find and save method provided by eloquent and return the user object in if statement and it will work.
$user = User::where('email', $email)->first();
$user->firstname = $firstname;
$user->lastname = $lastname;
$user->save();
return $user;
Try like this and it should work.
$user = User::find($usuario->ID);
$user->rol_id = 1;
$user->save();
}
}
}
return view('dashboard.index')->with(compact('cantReferidosDirectos', 'cantReferidosIndirectos', 'cantReferidosActivos', 'fechaProxActivacion', 'new_member',
'cantventas', 'cantventasmont', 'fullname', 'rangos', 'cantAllUsers', 'rankingComisiones', 'rankingVentas', 'permiso','noticias', 'contTicket', 'moneda',
'nombreRol'
));
}
/**
* Permite actualizar las informacion de los usuarios
*
* #access public
* #return view
*/
public function ActualizarTodo()
{
$comisiones = new ComisionesController;
$comisiones->ObtenerUsuarios();
$todousers = $this->generarArregloUsuario(Auth::user()->ID);
foreach ($todousers as $user ) {
if ($user['rol'] != 0) {
$activacion = new ActivacionController;
$activacion->activarUsuarios($user['ID']);
}
}
Arguments
"compact(): Undefined variable: fechaProxActivacion"
Como soluciono este error

Resources