I am new to laravel and I experience some trouble. I try to obtain data stored in two different tables and display them:
News.php (model)
public static function Data($category) {
$perPage = config('var.news.perPage');
if ($category) {
$news = News::orderBy('id', 'desc')->where('category', $category)->SimplePaginate($perPage);
} else {
$news = News::orderBy('id', 'desc')->SimplePaginate($perPage);
}
return $news;
}
This is how I grab all data from News table which struct is:
id, title, body, created_at updated_at, created_by, updated_by, category
The category column contains values separated by comma, e.g. 1,2,3,4
Now, I have another table, News_Cat which has id, name columns.
In another method I try to grab the filters names against values stored in category column of News table
public static function getFilterNames($id) {
$filters = DB::table('News_Cat')
->select('News_Cat.name as name')
->leftJoin('News', DB::raw('CAST(News_Cat.id as nvarchar)'), DB::raw('ANY(SELECT(News.category))'))
->where('News.id', $id)
->get();
return $filters;
}
However, it completely does not work. What I try to achieve is to display filter name in view.blade as 'name' value for specified filter from News_Cat
#if($news->count())
#foreach($news as $article)
<a href="{{ route('news.show', $article->id) }}" class="item angled-bg" data-filters="{{ $filters }}">
<div class="row">
So as result I would get e.g. data-filters="news, update, hot, latest"> instead data-filters="1,2,3,4">
Thank you
You should use eloquent!
In your News Model
public function getFiltersAttribute(){
$categories = explode(',', $this->category);
return implode(', ', NewsCat::find($categories)->pluck('name')->toArray());
}
then in your view :
{{ $article->filters }}
will output news, update, hot, latest
BUT
You should use a pivot table between your categories and your news, it would be much easier.
This method can't allow you to eager load the relationship and make a request for each news
If you can't change your database structure, I can propose you this:
In the boot method of your AppServiceProvider:
Config::set('tags', NewsCat::all());
THEN
public function getFiltersAttribute(){
$categories = explode(',' $this->category);
return implode(', ', config('tags')->whereIn('id', $categories)->pluck('name')->toArray());
}
MANY TO MANY METHOD
I am using laravel naming convention for the table :
news, categories_news (the pivot), and categories
You will have 2 models : New and Category
In your New Model
public function categories(){
return $this->belongsToMany(Category::class)
}
in your Category Model :
public function news(){
return $this->belongsToMany(New::class);
}
if you are not using laravel naming conventions, you will have to customize these raltionship like this : https://laravel.com/docs/5.5/eloquent-relationships#many-to-many
Related
i have two tables food table and restaurants table which are all related by restaurant id
This is the relationship in the food models
public function restaurant(){
return $this->belongsTo('App\Restaurant');
}
This is the food table
$table->bigIncrements('id');
$table->timestamps();
$table->integer('price');
$table->integer('food_item');
$table->integer('restaurant_id');
This is the relationship in the restaurants model
public function foods(){
return $this->hasMany('App\Food');
}
When the user puts input q which is the search term of food item i need it to produce all restaurants which food item according to the search term
Here is the query i wrote but returns 0 results when i do return json_encode($foodsAll);
public function search(Request $request){
$foodsAll = Restaurant::whereHas('foods',function($query) use ($request){
$query->where('food_item','like','%'.$request->q.'%');
});
}
You are missing get().
public function search(Request $request){
$foodsAll = Restaurant::whereHas('foods',function($query) use ($request){
$query->where('food_item','like','%'.$request->q.'%');
})->get();
}
I want to create a database table in laravel using migration, I have 4 columns in that table
1) ID(Auto-Increment, Primary Key)
2) Book Name
2) Book ID
4) Price
Now, I need to automatically fill value of BOOK ID column, value like this
Book ID = 'Book_1' (here "Book_" is prefix & 1 is value from ID column)
so for auto increment we create like this
$table->increments('id');
I need for BookID, how to write for that.
possible solution.
NOTE : not in table creation (migration) but when actually storing data.
create an ordinary varchar column to store name.
$table->string('name');
in the AppServiceProvider class boot() function. do something like this.
let's imagine your particular model is 'Book'
Book::created(function ($book) {
$book->update(['name' => 'Book_' . $book->id]);
}
this will bind an event to the 'Book' creation. when every time new book is saved to the database, name will automatically generate and save.
If the BookID column is only for the representational purpose you can add an accessor.
public function getBookIdAttribute()
{
return 'Book_' . $this->attributes['id'];
}
else, you can accomplish by adding this to your model,
protected static function boot()
{
parent::boot();
static::created(function ($model) {
$model->BookID = 'Book_' . $model->id;
$model->save();
});
}
Working on a search functionality on Laravel App(Blog/Posts).
There are multiple types of posts (each having a separate table in the database)
Like Business posts, Social Life posts etc..
Below is the search function on SearchController
class SearchController extends Controller
{
public function search(Request $request, $query = null)
{
if($query == null)
return redirect()->route('home');
$search = Business::where([['title','like','%'.$query.'%'],['status','=',1]])
->orWhere([['description','like','%'.$query.'%'],['status','=',1]])
->paginate(10);
return view('front.search',[
'results' => $search,
'query' => $query
]);
}
}
So basically my question is how to add other types of Post's table also?
My main motive is that when someone searches for anything, the result should be fetched from all types of posts table(business, nature, life & so on..).
You have to maintain common id in both the table
NOTE: Join is the preferable method
$querys = DB::table('Business')->where([['Business.title','like','%'.$query.'%'],['Business.status','=',1]])
->orWhere([['Business.description','like','%'.$query.'%'],['Business.status','=',1]]);
$querys->join('socialtable','socialtable.userid','=','Business.userid');
// Just join the social table
$querys->where('socialtable.title', 'like','%'.$query.'%');
$result = $querys->paginate(10);
If you have a model called Book, like this:
class Book extends Model
{
/**
* Get the author that wrote the book.
*/
public function author()
{
return $this->belongsTo('App\Author');
}
}
Then you can retrieve all of your books with authors like this:
$books = App\Book::with(['author'])->get();
Check out Eager loading from Laravel documentation.
Just add table name before every field
$querys = DB::table('Business')->where([['Business.title','like','%'.$query.'%'],['Business.status','=',1]])
->orWhere([['Business.description','like','%'.$query.'%'],['Business.status','=',1]]);
$querys->join('socialtable','socialtable.userid','=','Business.userid');
// Just join the social table
$querys->where('socialtable.title', 'like','%'.$query.'%');
$result = $querys->paginate(10);
I would like to sort the products by its sku. How would that be possible ?
I tried to add in ProductRepository.php:
...
$queryBuilder = $this->getCollectionQueryBuilder();
$queryBuilder
->innerJoin('product.taxons', 'taxon')
->innerJoin('product.variants', 'variant')
->andWhere('taxon = :taxon')
->setParameter('taxon', $taxon)
;
foreach ($criteria as $attributeName => $value) {
$queryBuilder
->andWhere('product.'.$attributeName.' IN (:'.$attributeName.')')
->setParameter($attributeName, $value)
;
}
$queryBuilder->orderBy('variant.sku');
...
but got:
Cannot select distinct identifiers from query with LIMIT and ORDER BY
on a column from a fetch joined to-many association. Use output
walkers.
Finally what I did: Sorted the products just before output in a custom twig function:
macros.html.twig
{% set products = skusort(products) %}
In my SkusortExtenstion.php (as of PHP 5.3)
$product->getIterator()->uasort(function($a, $b){
return $a->getMasterVariant()->getSku() > $b->getMasterVariant()->getSku();
});
return $product;
Was afraid of performance issue as there's a lot of products but seems to be very fast.
Another way is to reload method getPaginator() of class Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository. In that case we must instantinate DoctrineORMAdapter with $useOutputWalkers flag (the latest constructor argument).
So, put the folowing code in your ProductRepository.php:
/**
* {#inheritdoc}
*/
public function getPaginator(QueryBuilder $queryBuilder)
{
return new Pagerfanta(new DoctrineORMAdapter($queryBuilder, true, true));
}
I'm new to Laravel and still getting my head around Eloquent. I have two models (A, B) with a many-to-many relationship (belongsToMany in both models) with the following fields:
A: id, name, text, etc..
B: id, name, description, info, etc...
A_B: id, A_id, B_id
When retrieving an object of 'A', I just want to retrieve the 'id' and 'name' of its related 'B', rather than the entire 'B' objects - as these could be large. Is a way to retrieve only specific columns from a related model, or would it be better to separate my tables so that 'id' and 'name' are on their own?
I'm not really sure if grabbing all of the columns from table 'B' would effect speed of the query too much, but you can try this:
Model class for table 'A_B'
class A_B extends Eloquent {
public function a(){
$this->hasMany('A', 'id', 'a_id');
}
public function b(){
$this->hasMany('B', 'id', 'b_id');
}
}
In your model for table 'B'
class B extends Eloquent {
//Hide fields from displaying in your query
protected $hidden = array('description', 'info');
}
In your controller:
//Get all records with A and B
$all = A_B::with('a')->with('b')->get();
return View::make('view')->with('all', $all);
In your view:
#if($all->count() > 0)
#foreach($all as $record)
{{ $record->id }}
{{ $record->name }}
#endforeach
#else
There are no records to be displayed
#endif