How to search in multi column? - laravel

I need to search in users table with the name and if there no match with any name in table transfer into category table which has relation with each one of user.
the code of html:
<form action="{{ route('search') }}" method="GET">
<input type="search" class="input" name="q" placeholder="Search">
</form>
Controller code (my shut):
public function search(Request $request)
{
$users = new User;
$req = $request->input('q');
$users = $users->where('name','LIKE','%'. $req .'%')->whereHas('category', function ($query) use($req) {
$query->where('name','LIKE','%'. $req .'%');
});
$users = $users->unverified()->active()->orderBy('id','desc')->paginate(16);
return view('frontend.search.search', compact('users'));
}
category has relation with user:
public function category()
{
return $this->belongsTo('App\Category');
}
I need to say if there is no name ( users table ) check the category one.

You will need to use a orWhere method, which means or do the other. To avoid weird logic it is the easiest approach to wrap it in a where closure.
$users = User::where(function ($query) use($req) {
$query->where('name','LIKE','%'. $req .'%')
->orWhereHas('category', function ($query) use($req) {
$query->where('name','LIKE','%'. $req .'%');
});
});
This means your code will find elements with the name or with the given category. There is an edge case where it will find by the category name even if user is set. But avoiding that, is not as straight forward as this.

Related

Relationship with paginate

I need to create a dynamic link to take the user to the last page of the laravel page. For example, if there is a pagination, I need to include lastPage () at the end of the url www.site.com/forum/slug?page=2
otherwise it goes to the normal page.
But I need to do this logic on another controller, which in turn is not working. See my relationships and how I'm doing:
public function grupoPerfil($slug) {
$grupo = Grupo::where('slug', $slug)->first();
$comments = Comment::whereHas('relato', function ($query) use ($grupo) {
return $query->where('grupo_id', $grupo->id);
})->paginate(10);
if($grupo){
$rels = $grupo->relatos()->with('user')->paginate(20);
return view('grupo', compact(['grupo', 'rels','comments']));
}
abort(404);
}
my blade:
#foreach($rels->sortByDesc('updated_at') as $r)
<card-relatos
url="{{localized_route('relatoUser', [$r->grupo->slug, $r->slug])}}"
getpaginate="{{ $comments->lastPage() }}"
</card-relatos>
#endforeach
But getpaginate always returns 2, as it is not related to relato_id. How do I solve this?
This is what I have done:
return Product::whereHas('category', function ($query) use ($slug) {
$query->where('slug', $slug);
})->paginate(15);

Laravel: Passing data to view through route after querying

I recently asked a question about defining many to many relationships (using belongsToMany) and it was a huge help. So now in my models I have:
Users model
public function subjects()
{
return $this->belongsToMany('App\Subject', 'users_subjects', 'user_id', 'subjects_id');
}
Subjects model
public function users()
{
return $this->belongsToMany('App\User', 'users_subjects', 'subject_id', 'user_id');
}
This way I establish a relationship between users and subjects via the users_subjects table. My next step was to create a controller, SubjectsController, which ended up looking like this:
class SubjectsController extends Controller
{
// returns the view where subjects will be displayed
public function index()
{
return view('profiles.professor.prof_didactic_subjects');
}
// get users with subjects
public function getSubjects()
{
$subjects = User::with('subjects')->get();
}
// get a single user with a subject
public function getSubject($id)
{
$materia = User::where('id', '=', $id)->with('subjects')->first();
}
}
I'm not very sure about the code in the controller though.
The final step is where it gets tricky for me, even after reading the docs: I want to pass each result to the view, so I can have multiple tiles, each populated with data from subjects the user is associated with:
#foreach ($subjects as $subject)
<div class="tile is-parent">
<article class="tile is-child box">
<p class="title">{{ $subject['name'] }}</p>
<div class="content">
<p>{{ $subject['description'] }}</p>
</div>
</article>
</div>
#endforeach
I tried many different route configurations, but kept getting either the undefined variable error or trying to access non-object error.
What's the proper course of action here? I feel I'm missing something very basic. Thanks in advance for any help.
The answer
The solution provided below by #Sohel0415 worked perfectly. My index() method on the controller now looks like this:
public function index()
{
// temporary value while I figure out how to get the id of the current user
$user_id = 6;
$subjects = Subject::whereHas('users', function($q) use ($user_id){
$q->where('user_id', $user_id);
})->get();
return view('profiles.professor.prof_didactic_subjects')->with('subjects', $subjects);
}
My route looks like this:
Route::get('/professor', 'SubjectsController#index');
I was pretty lost, so this absolutely saved me, thanks again :)
You need to pass $subjects to your view. You can use compact() method for that like -
public function index()
{
$subjects = Subject::with('users')->get();
return view('profiles.professor.prof_didactic_subjects', compact('subjects'));
}
Or using with() method like -
public function index()
{
$subjects = Subject::with('users')->get();
return view('profiles.professor.prof_didactic_subjects')->with('subjects', $subjects);
}
If you want to get Subject for a particular user_id, use whereHas() -
$subjects = Subject::whereHas('users', function($q) use ($user_id){
$q->where('user_id', $user_id);
})->get();

Simple search in laravel

I'm trying to build a search system in my small laravel project but considering that I'm still a beginner I can't figure how this should work..
Basically, I have a controller which returns an index page with all the users. In the index page I have multiple select tags where you can choose an option and filter the users.
Here's my index method:
public function index(){
$users = User::all();
$service = Service::all();
return view('browse.index', compact('users','service'));
}
Now, the thing is, I have a relationship built between users and services. So, each user hasMany services. With that in mind, when I'm building the search function I want to be able to access the user service.
Something like this:
$category = $request->input('category');
foreach ($users as $user) {
$serviceFound = $user->service->where('category', 'LIKE', '%' . $category . '%');
}
Of course this doesn't work because considering that I have a get route for my index, I don't know how to set up the form so I can use the $request.. I hope this is clear...Maybe you guys can help me with setting up the form/route and clear my mind on how should I do this...
Build a simple form using GET as well. Simple Example
<form action="" method="GET">
<input type="text" name="category" required/>
<button type="submit">Submit</button>
</form>
In your controller you do
public function index(Request $request){
$category = $request->input('category');
//now get all user and services in one go without looping using eager loading
//In your foreach() loop, if you have 1000 users you will make 1000 queries
$users = User::with('services', function($query) use ($category) {
$query->where('category', 'LIKE', '%' . $category . '%');
})->get();
return view('browse.index', compact('users'));
}
Eager loading will work only if you have your relationships setup properly.
Keep your route unchanged the way it is now.
In your controller:
public function index(\Request $request)
{
return $request::all();
}
In your routes:
Route::get('searchtest', 'SearchController#index');
Example url:
http://localhost:8000/searchtest?search=search_string&category=socks
And finally, the output
{
"search": "search_string",
"category": "socks"
}
You can also do $category = $request::get('category'); to get only the category as a string.

Display tags in article based on language?

This is my relationship:
article:
public function tags(){
return $this->belongsToMany('App\Models\ATags', 'article_tags','article_id', 'article_tag_id');
}
language:
public function tags(){
return $this->hasMany('App\Models\ATags', 'language_id');
}
Here i get all tags for specific language. I want now to display all tags for that language for that specific article.
foreach($languages as $language){
$tags[] = $language->tags;
}
Any suggestion how can i do that?
I tried this but i get an error
$tags1 = $tags->whereHas('articles', function ($query) {
$query->where('id', '=', $article_id);
})->get();
I have two languages, and what im trying to get is to have tags for that two languages.
This is my controller:
public function edit($article_id){
$user = $this->user;
$languages = $this->languages;
$article = Articles::findOrFail($article_id);
$article_trans = $article->translations;
foreach($languages as $language){
$tags = $language->tags;
}
$tags1 = $tags->whereHas('articles', function ($query) {
$query->where('id', '=', $article_id);
})->get();
}
This is view for tags:
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="form-group">
<label class="form_title">ARTICLE TAGS</label>
<input type="text" name="tags[{{$article_tran->language->code }}]" class="form-control tokenfield" value="{{ $user_tags }}" />
</div>
seems your closer is not getting the value of article_id assuming your ATag model has relation belongsToMany defined as articles.
public function edit($article_id){
$user = $this->user;
$languages = $this->languages;
$article = Articles::findOrFail($article_id);
$article_trans = $article->translations;
$tags = [];
foreach($languages as $language){
//because of loop take array of tags
$tags[] = $language->tags()->whereHas('articles', function($query) use($article_id){
$query->where('id', '=', $article_id);
})->get();
}
}
consider the use($article_id) in whereHas closure and whereHas doesn't work with collection when you call $language->tags which returns the collection not builder
also have you defined the articles relation properly in ATag model?

how can fetch value from database

when we can type a letter in textbox.. onkeyup action done. go to search database and than display the corrosponding words below..
eg: i enter A,then display Apple,Ant(my database table contain this words staring letter is A) how can fetch value from database .
my controller.php is
public function executeSearch()
{$keywords=Input::get('keywords');
$users=User::all();
$searchUsers=new\Illuminate\Database\Eloquent\Collection();
foreach($users as $u)
{
if(Str::contains(Str::Lower($u->name),Str::Lower($keywords)))
$searchUsers->add($u);
}
return View::make('searchUsers')
->with('searchUsers',$searchUsers);
}
Simply use SQL's LIKE:
$users = User::query();
foreach($keywords as $keyword){
$users->orWhere('name', 'LIKE', '%'.$keyword.'%');
}
$users = $users->get();
Then pass it to your view:
return View::make('searchUsers')->with('users', $users);
And loop over the results in the view:
#foreach($users as $user)
Name: {{ $user->name }}
#endforeach

Resources