How can i decode json data if i saved in array laravel? - laravel

I have 2 two tables: one is an admission and the other is a class table. I am saving class id in admission class field of admission table by json_encode method.
My controller
public function store(Request $request)
{
$inputs = $request->all();
$admission = new Admission;
$admission->school_id = Auth::User()->id;
$admission->admission_classes=json_encode($inputs['admission_classes']);
$admission->save();
}
My index function
public function index(Request $request) {
$school_id= Auth::user()->id;
$admissions= Admission::where('school_id',$school_id)->orderBy('id','desc')->paginate(10);
return view('frontend.index',compact('admissions','active_class'));
}
My view
#foreach($admissions as $i => $admission)
{{ $admission->admission_classes }}
#endforeach
I am getting data in this way:-
["1","2","4","5","6","7","8","9"]
But I want to get in this format:
Nursery,Class 1, Class2, Class3 etc
My class controller
class Classes extends Authenticatable
{
use EntrustUserTrait;
use Billable;
use Messagable;
protected $fillable = [
'name','status'
];
}

You need to save integer value in as json array and do the following code
$integerIDs = array_map('intval', $inputs['admission_classes']);
$admission->admission_classes= json_encode($integerIDs);
public function index(Request $request){
$admissions = DB::select('SELECT a.*, GROUP_CONCAT(c.name) as classes FROM academy as a LEFT JOIN class c ON JSON_CONTAINS(a.classes, CAST(c.id as JSON), '$') WHERE a.school_id =2 GROUP BY a.id');
$admissions = $this->arrayPaginator($admissions, $request);
return view('frontend.index',compact('admissions','active_class'));
}
public function arrayPaginator($array, $request)
{
$page = Input::get('page', 1);
$perPage = 10;
$offset = ($page * $perPage) - $perPage;
return new LengthAwarePaginator(array_slice($array, $offset,
$perPage, true), count($array), $perPage, $page,
['path' => $request->url(), 'query' => $request->query()]);
}
I have not checked the code hope this will help u to continue.......

The best way to achieve this would be to have a one-to-many relationship with App\Classes.
However, since you already have something up and running, I would probably do it like this.
First, I would cast admission_classes to an array. This makes sure that admission_classes will always be casted to an array whenever it is fetched. It makes it easier for us to work with it.
protected $casts = [
'admission_classes' => 'array'
];
Finally, while fetching your admission records, you would also need to map over it and hydrate the Classes from its ids. This is how I'd try to achieve it.
$admissions = Admission::where('school_id',$school_id)
->orderBy('id','desc')
->paginate(10)
->map(function($admission) {
return array_map(function($class) {
$class = Classes::find($class);
return isset($class) ? $class->name : '';
}, $admission->admission_classes);
});
You will notice that I wrapped the Classes::find() method into the optional() helper. This is because, in case, a record is not found, it will not fail.
Finally, to print your class names in your blade, you would do something like this:
implode(',', $admission->admission_classes);

Related

eloquent with() in multiple where() clouse

I am trying to filter results of relationship table.
public function read_projects_by_coords(Request $request)
{
$from_lat = $request->get("from_lat");
$to_lat = $request->get('to_lat');
$from_lng = $request->get('from_lng');
$to_lng = $request->get('to_lng');
$projects = Project::with(["details" => function($query) use ($from_lat, $from_lng, $to_lat, $to_lng){
return $query->where("details.lat", ">", $from_lat)
->where("details.lat", "<", $to_lat)
->where("details.lng", ">", $from_lng)
->where("details.lng", "<", $to_lng);
}])->get();
return response()->json($projects);
}
But when I run the above details(child) coming with a empty/null result and parent/Project table not filtered. I returns all...
For example $projects = Project::with(["details"])->get(); this is works without a problem. But when I try to filter Project Model with the where inside the with() I can't get the detail object records, and parent is not filtered.
to anyone who wants to see the models parent and child
class Project extends Model
{
protected $table = "projects";
protected $guarded = [];
protected $with = ["details"];
public function details(){
return $this->hasOne("App\Models\Detail");
}
}
class Detail extends Model
{
protected $table = "details";
protected $guarded = [];
public function project(){
return $this->belongsTo("App\Models\Project");
}
}
What am I am missing?
To filter the Project table to only select the ones with some Details matching your parameters, you need to use whereHas. You need to keep your with clause too in order to have the details property correctly populated.
I would use a callback to not repeat the same conditions
$callback = function($query) use ($from_lat, $from_lng, $to_lat, $to_lng) {
$query->where("lat", ">", $from_lat)
->where("lat", "<", $to_lat)
->where("lng", ">", $from_lng)
->where("lng", "<", $to_lng);
}
$projects = Project::with(['details' => $callback])
->whereHas('details', $callback)
->get();
return response()->json($projects);

Call function from model by passing a variable

I am approaching Laravel 7, and I am lost in a banality I guess. I create a function in the model that picks up the count of how many posts a category has, then passing the ID parameter.
I call this function in the controller, which then picks up the variable in the views.
It gives me an error:
Object of class Illuminate\Database\Eloquent\Builder could not be
converted to string
How can I solve it?
MODEL
public function scopeCountActivePostCategory($id)
{
$query = DB::table('post')->where([
['status', 1],
['category', $id],
]);
return $query->count();
}
CONTROLLER
// get details category by slug
// preleva dettagli categoria by slug
$detailCat = DB::table('categories')->where('slug', $slug)->first();
// get stories
$post = DB::table('post')
->orderByDesc('id')
->where('category', $detailCat->id)
->where('status', 1)
->paginate($set->app_result_x_page);
return view('category')->with([
'posts' => $posts,
'set' => $set,
'totalActivePost' => Post::CountActivePostCategory($detailCat->id),
'detailCat' => $detailCat
]);
You're missing a get() in your query. The way you have it, you're trying to count query builder (SQL query string) instead of the collection you would get by putting get() on the end of your builder. Change your code to this:
public function scopeCountActivePostCategory($id)
{
$query = DB::table('post')->where([
['status', 1],
['category', $id],
])->get(); //Get here
return $query->count();
}
EDIT
The calling of CountActivePostCategory function might be a problem as well. You are calling static function CountActivePostCategory but you didn't define it as static in your Post model. Change your function to this:
public static function countActivePostCategory($id){
//body
}
And then call it in your controller like this:
'totalActivePost' => Post::countActivePostCategory($detailCat->id)

Dynamic search function Photo album

I am trying to create a dynamic serch function to my PhotoAlbumn project. So I have installed Nicolaslopezj Searchable. However it does not work propertly as yet.
Error
Illuminate\Database\Eloquent\RelationNotFoundException
Call to undefined relationship [albums] on model [App\Photo]
Model
use Illuminate\Database\Eloquent\Model;
use Nicolaslopezj\Searchable\SearchableTrait;
class Photo extends Model{
use SearchableTrait;
protected $searchable = [
/**
* Columns and their priority in search results.
* Columns with higher values are more important.
* Columns with equal values have equal importance.
*
* #var array
*/
'columns' => [
'albums.name' => 10,
'photos.title' => 10,
'photos.info' => 10,
'albums.title' => 5,
],
'joins' => [
'albums' => ['photos.id','albums.id'],
],
];
protected $fillable = array('photo','title','info','album_id');
public function album(){
return $this->belongsTo('App\Album');
}
PhotoController
public function search(Request $request){
$query = $request->input('query');
$result = Photo::search($query)
->with('albums')
->get();
return view('search.results')->with('result', $result);
}
This relationship worked prior to using Nicolaslopezj Searchable.
You have an extra s in your relationship.
Replace
$result = Photo::search($query)
->with('albums')
->get();
by
$result = Photo::search($query)
->with('album')
->get();

Orwhere has method does not allow null

enter image description hereI am trying to implement a many to many relationship search with 2 models.
i get input from multiple checkbox values and want to search for items that match A or B when there is an input of data.
I read this url and wrote the same logic.
https://laracasts.com/discuss/channels/laravel/many-to-many-relationship-with-2-pivot-table-data-search
public function search(Request $request)
{
$languages = $request->lang;
$fields = $request->field;
$agencies = Agency::with('languages')->with('specialized_fields')
->orWhereHas('languages', function($query) use ($languages) {
$query->whereIn('language_id', $languages);
})
->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
dd($agencies);
}
i expected to achieve A or B search but instead I got this error.
Argument 1 passed to Illuminate\Database\Query\Builder::cleanBindings() must be of the type array, null given, called in /var/www/jtf/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php on line 907
it seems that it causes this error if either A or B is null, but why??? Does the OrWhereHas method work only when theres an input??
/added info/
my error message
my agency model
class Agency extends Model {
protected $guarded = [
'id'
];
public function languages(){
return $this->belongsToMany('App\Language');
}
public function specialized_fields(){
return $this->belongsToMany('App\SpecializedField');
}
public function region(){
return $this->hasOne('App\Region');
} }
I believe it's because either $languages or $fields is null.
Since ->whereIn() is expecting an array, but you're passing null.
You just need to make sure you're passing an array.
$languages = array_filter((array) $request->lang); // cast to array & remove null value
$fields = array_filter((array) $request->field);
$agencies = Agency::with('languages', 'specialized_fields')
->orWhereHas('languages', function($query) use ($languages) {
$query->whereIn('language_id', $languages);
})
->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
I'm speculating that you started your where query chain with an orWhereHas() which may have caused the problem, try starting with whereHas() instead.
public function search(Request $request){
$languages = $request->lang;
$fields = $request->field;
$agencies = Agency::with('languages', 'specialized_fields') // you can get away by just using one with(), not needed but its cleaner this way
->whereHas('languages', function($query) use ($languages) { // previously orwherehas
$query->whereIn('language_id', $languages);
}) ->orWhereHas('specialized_fields', function($query) use ($fields) {
$query->whereIn('specialized_field_id', $fields);
})
->get();
dd($agencies);
}

Calling eloquent relation multiple times doesn't return data

I'm having this strange behavior in Laravel 5.1 where when I call the relation of an eloquent model more than once within the same code execution, then the second time it doesn't have the data.
class Items extends Eloquent {
public $table = 'items'
public function subItems() {
return $this->hasMany(Item::class, 'items_id');
}
}
class Item extends Eloquent {
public $table = 'items_item'
public $fillable = ['items_id'];
}
$items = Items::create();
Item::create([
'items_id' => $items->id,
]);
Item::create([
'items_id' => $items->id,
]);
// works
$first = $items->subItems;
// no data
$second = $items->subItems;
// works
$third = $items->subItems()->get();
Is this normal behavior? Do i have to somehow reset something before calling the relation again?
I don't know the purpose of your repeated same action. If your $first,$second,$third variables are in same function, don't repeat it again.
Instead use,
$first = $items->subItems;
$second = $first;

Resources