Laravel: How to assign Organization to a user - laravel

I want to assign an organization to a user but what happens in my code is that when I create a new organization and it's ID is 1, it automatically assigns itself to user ID 1 also.
This is my AssignOrgToUser controller:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\organizations;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class AssignOrgToUserController extends Controller
{
public function assignOrg(Request $request, $id)
{
$users = User::find($id);
if(is_null($users)){
return response()->json(["message"=>"User not found!"], 404);
}
$rules=[
'organization'=>'required',
];
$validator = Validator::make($request->all(), $rules);
if($validator->fails()){
return response()->json($validator->errors(),400);
}
$data = $request->validate([
'organization'=>'required',
]);
$orgs = organizations::where('id', '=', $request->organization)->first();
if(is_null($orgs)){
return response()->json(["message"=>"Organization not found!"], 404);
}
$orgs= $users->save();
if($orgs){
return ["result"=>"ORG Added"];
}else{
return ["result"=>"ORG not Added"];
}
// $users->save([$orgs]);
// return response(['message'=>"Organization has beed added", $users]);
}
}
Organization Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class organizations extends Model
{
public $table = "organizations";
use HasFactory;
protected $guarded = [];
public function users(){
return $this->belongsTo('App\Models\User'); #if column not found indicate the column name
}
}
Any kind of help/suggestions will be greatly appreciated. Thank you!!

Replace this $orgs= $users->save(); with the below code
For update use associate method do like this (in your Case)
$orgs = Organisation::create(['someColumn' => $request->someColumn]);
$orgs->users()->associate($users);
$orgs->save();
for more https://laravel.com/docs/8.x/eloquent-relationships#inserting-and-updating-related-models

It seams like the problem came from you Request URL, you have define you Controller to receive a paramater name id with that I can presume you have define the Route like this
Route::post("/assign_organization/{id}", [AssignOrgToUserController::class, "assignOrg"]);
If the request url contain a user ID which is 1 any time you'll try to create an organization it will be attached to a user which ID is 1. as you are retrieving the user based on the id get from the URL
$user = User::find($id);
If you want to assign an organization with a different User ID, you should pass that User ID in you request body. and that won't consider the URL Body
$user = User::find($request->get("user_id"));

Related

Create filter in laravel API controller

Hi i want to create a filter to show mosque with event or activities only. Any idea to display the mosque with activities or events only ?. This one from back-end that later will be fetch using react
namespace App\Http\Controllers;
use App\Event;
use App\Mosque;
use App\Activity;
use Illuminate\Http\Request;
class NotificationController extends Controller
{
public function list()
{
$mosques = Mosque::get();
$array = array();
foreach ($mosques as $mosque) {
array_push($array, [
'mosque_name' => $mosque->name,
'mosque_image'=> $mosque->image
]);
}
return $array;
return response()->json(['result' => $mosques]);
}
public function show(Request $request)
{
$mosque = Mosque::find($request->mosque_id);
$mosque->activities;
$mosque->events;
return response()->json(['result' => $mosque]);
}
}
To filter rows from database, which has particular relationship, you can use whereHas() function on QueryBuilder Instance.
$mosques = Mosque::whereHas('events')
->orWhereHas('activities')
->get();
This function will only returns mosques which has activities or events, other mosques will not fetch.
Also if you only need the name and the image you can filter them too
$mosques = Mosque::whereHas('events')
->orWhereHas('activities')
->get(['name','image']);
You can try this
public function show(Request $request)
{
$mosque = Mosque::find($request->mosque_id);
$mosque->activities;
$mosque->events;
return response()->json(['result' => $mosque->events ]);
}

How to make dynamic query in laravel 5 with model and controller

i have Add query in codeigniter like this:
in controller:
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log=$this->model->add_data($data);
And in model add_data function like this:
function add_data($data)
{
return $this->db->insert($data['table'],$this->security->xss_clean($data['val']));
}
But In Laravel 5 I have:
$name=$Request->input('name');
$lname=$Request->input('lname');
$myItems = array(
'first_name'=>$name,
'last_name'=>$lname
);
DB::table("tbl_user")->insert($myItems);
My question is, how can we make table field dynamic in Laravel and call that function through model.
Also, how can I call that function from model? Any help please. I want a dynamic query
You can write a helper function
//create a helper function
function addModelData($arrayData = [])
{
return \DB::table($arrayData['table'])->insert($arrayData['val']));
}
//in your controller or any place you like
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log = addModelData($data);
You could create a model as described in official documentation:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'tbl_user';
// If your primary key is not 'id'
protected $primaryKey = 'model_id';
}
Now in your controller you can use this model:
namespace App\Http\Controller;
use App\User;
use Illuminate\Http\Request;
class MyController extends Controller {
public function myAction(Request $request){
$user = new User();
$user->last_name = $request->input('lname');
$user->first_name = $request->input('name');
$user->save();
}
}
You also could use mass assignment. But before you have to set the $fillable attribute in your model:
protected $fillable = ['first_name', 'last_name'];
Now you can use mass assignment in your controller:
$user = User::create([
'first_name' => $request->input('name'),
'last_name' => $request->input('lname')
]);
// alternatively:
$user = User::create($request->only(['name', 'lname']));

PhpUnit - mocking laravel model with relations

I'm trying to mock (it's example only) $user->posts()->get().
example service:
use App\Models\User;
class SomeClass{
public function getActivePost(User $user): Collection
{
return $user->posts()->get();
}
}
and my Model:
and Model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use \App\Models\Post;
class User extends Model
{
public function posts() : HasMany
{
return $this->hasMany(Post::class);
}
}
this doesn't work:
$this->user = Mockery::mock(User::class);
$this->user
->shouldReceive('wallets->get')
->andReturn('test output');
error:
TypeError: Return value of Mockery_2_App_Models_User::posts() must be an instance of Illuminate\Database\Eloquent\Relations\HasMany, instance of Mockery_4__demeter_posts returned
without return type hint (on post() method) everything is ok. Must I modify andReturn()? idk how
This error can be solved by using the alias prefix with a valid class name. Like the following:
$m = m::mock('alias:App\Models\User');
More information can be found at the official documentation http://docs.mockery.io/en/latest/reference/creating_test_doubles.html#aliasing
Alternatively you can use like this.
use App\Models\User;
class SomeClass{
public function getActivePost(User $user): Collection
{
$user->load('posts');
return $user->posts;
}
}
First you need to mock post, then add it to Collection (don't forget to use it in the top). Then when you call posts attribute its takes mocked $posts. In this case it will not throw error about return type.
use Illuminate\Database\Eloquent\Collection;
$post = $this->mock(Post::class)->makePartial();
$posts = new Collection([$post]);
$this->user = Mockery::mock(User::class);
$this->user
->shouldReceive('getAttribute')
->with('posts');
->andReturn($posts);
Also i wouldn't use mocks here. There is absolutely no need for it. So the unit test i write would be:
Create a user.
Create some posts authored by the user.
Perform assertions on user & posts.
So the code will then be something like this in my test:
$user = factory(User::class)->create();
$posts = factory(Post::class, 5)->create(['user_id' => $user->id]);
$this->assertNotEmpty($user->id);
$this->assertNotEmpty($posts);
$this->assertEquals(5, $posts->fresh()->count());
$this->assertEquals($user->id, $post->fresh()->first()->user_id);
if you want to test the relationship you can:
/** #test */
function user_has_many_posts()
{
$user = factory(User::class)->create();
$post= factory(Post::class)->create(['user_id' => $user->id]);
//Check if database has the post..
$this->assertDatabaseHas('posts', [
'id' => $post->id,
'user_id' => $user->id,
]);
//Check if relationship returns collection..
$this->assertInstanceOf('\Illuminate\Database\Eloquent\Collection', $user->posts);
}

FatalErrorException Laravel 5.3 Post Controllers

hi i have task title social network application using post and timeline
i have some problem
use App\Http\Controllers\Controller;
use App\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function postCreatePost(Request $request)
{
$post = new Post();
$post->body = $request['body'];
$request->user()->posts()->save($post);
return redirect()->('home');
}
}
this is my Post modle please check this code
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user (){
return $this->belongsTo('App\User');
}
}
Try to change
$post = new Post();
To
$post = new Post;
1) Change:
$post->body = $request['body'];
to:
$post->body = $request->get('body');
2) This line: $request->user()->posts()->save($post); also seems all wrong.
In your User model you need to tell eloquent that a user has many posts
public function posts()
{
return $this->hasMany('App\Post');
}
Then that line in your controller for a user with id = 1; $user = User::find(1) becomes:
$user->posts()->save($post)
3)return redirect()->('home'); has to be return redirect()->route('home');
4) Lastly, take some time to read the laravel documentation

Call to undefined method Illuminate\Database\Query\Builder::products()

i am trying to Implement smart Search engine in my Laravel 5 With help of This Tutorial
https://maxoffsky.com/code-blog/laravel-shop-tutorial-3-implementing-smart-search/
i changes some code because this tutorial for laravel 4
now i am stuck here When i type any keywords like cup i got error on Network tab in my deleveloper tool
Call to undefined method Illuminate\Database\Query\Builder::products()
Here is my Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use App\Http\Requests;
use App\Product;
use App\Category;
use Response;
class ApiSearchController extends Controller
{
public function appendValue($data, $type, $element)
{
// operate on the item passed by reference, adding the element and type
foreach ($data as $key => & $item) {
$item[$element] = $type;
}
return $data;
}
public function appendURL($data, $prefix)
{
// operate on the item passed by reference, adding the url based on slug
foreach ($data as $key => & $item) {
$item['url'] = url($prefix.'/'.$item['slug']);
}
return $data;
}
public function index()
{
$query = e(Input::get('q',''));
if(!$query && $query == '') return Response::json(array(), 400);
$products = Product::where('published', true)
->where('name','like','%'.$query.'%')
->orderBy('name','asc')
->take(5)
->get(array('slug','name','icon'))->toArray();
$categories = Category::where('name','like','%'.$query.'%')
->has('products')
->take(5)
->get(array('slug', 'name'))
->toArray();
// Data normalization
$categories = $this->appendValue($categories, url('img/icons/category-icon.png'),'icon');
$products = $this->appendURL($products, 'products');
$categories = $this->appendURL($categories, 'categories');
// Add type of data to each item of each set of results
$products = $this->appendValue($products, 'product', 'class');
$categories = $this->appendValue($categories, 'category', 'class');
// Merge all data into one array
$data = array_merge($products, $categories);
return Response::json(array(
'data'=>$data
));
}
}
my Product and Category model is blank because nothing on tutorial
Well based on your relationship between Product and Category Models you have to define product() function inside Category Model which represents your relationship. check This Link
For example - Assuming One-to-Many relationship (one category - Many Products) it will be like this -
Category Model -
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function product()
{
return $this->hasMany('App\Product');
// ^ this will change based on relationship
}
}
Product Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
// ^ this will change based on relationship
}
}

Resources