compact(): Undefined variable: users - mysql

here i am trying to get all the project->id, which match with team->project_id and relation is working but my using variable $users showing undefined. What could be the problem??
here is the controller code
public function index()
{
if (Auth::user()->role->id == 1) {
$projects = Project::all();
$teams = Team::all();
foreach ($teams as $team) {
$users = User::whereIn('id', $team->members)->get();
}
return view('project.index', compact('projects', 'users'));
}
}

You are not initializing the users out of the condition, so if there are no teams, there will be no users:
Try this instead:
$users = collect();
foreach ($teams as $team) {
$users = User::whereIn('id', $team->members)->get();
}
return view('project.index', compact('projects', 'users'));
But keep in mind that your loop will override the users each time, so you will just get the users from the last team only :D

Your problem is in your loop.
There are some blurry parts in your code.
1) In every loop you over-write your $users variable: I will assume that you need an array so try something like:
$users[] = User::whereIn('id', $team->members)->get();
*small note make sure that the column members in the Team table actually holds the ids.
2) The usage of compact() is correct but in case that your $user is empty then you will be trying to get an undefined property from it. In addition with the fact that you over-write your variable if the last itteration is empty then your $user is empty so you just return an empty array in your FrontEnd.
3) Using whereIn means that your column has more than 1 Ids. That's generally a bad practise. You should use a pivot table or store each record in different rows.
4) Predefine your array. If there are no teams, the foreach loop will never be accessed leaving you with a php error of undefined $users.

Related

How to compare array values with one to many relations in laravel

I have an input array of submaterials. $submaterials = [1, 2,3]
I am using lumen framework connected with mysql. I have a one to many relation with material and submaterial table. That's a material can have many submaterials.
Here my requirement is to get materials which have same submaterials in input. I only need to get materials which have exact same number of submaterials and same submaterials in input array
This is the query i have added
$submaterials_array = [12,13];
$otherrequests = for ($i = 0; $i < sizeof($submaterials_array); $i++)
{
$id = $submaterials_array[$i];
Offerrequest::whereHas('submaterialprops', function ($q) use ($id) {
$q->where('submaterial_id', $id);
});
}
$otherrequests = $otherrequests->get();
I have tried the query and I got a list of all offerrequests with submaterial id='12,13'. But I want to get only rows which have exact these submaterials(one to many relation). That means it should not return rows with submaterial 12,13,14 or 12,13,14,15,16.
Assuming you have a material model and your one to many relationship defined on the material model is called submaterials and that $submaterials is the array of ids. You could try using https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence
There may be other ways to do this but you could dynamically build the query by looping through the submaterials and adding a whereHas for every submaterial.
$materialQuery = Material::has('submaterials', '=', count($submaterials));
foreach($submaterials as $submaterial){
$materialQuery->whereHas('submaterials', function (Builder $query) use ($submaterial){
$query->where('id',$submaterial);
});
}
$material = $materialQuery->get();

Laravel Select Query Accessing Returned Data

I've been working with Laravel for a short time, and am confused about accessing data retrieved from queries. I'm trying to save data to variable but am getting the following:
Trying to get property of non-object
Queries tried:
$data = DB::table('table_1')->select('user_id', 'email')->where('email', '=', Input::get('email_address'))->get();
// also tried
$data = DB::table('table_1')->where('email', '=', Input::get('email_address'))->pluck('user_id');
// accessing data
$userID = $data->user_id;
Both return the same.
To elaborate a little bit, ->get() will return a Collection. You might iterate over it as an array, but you can profit from methods that this class offers. pluck is one of these.
That's why $userID = $data->user_id; wouldn't work.
first() did the trick, rather than get().
$data = DB::table('table_1')->select('user_id', 'email')->where('email', '=', Input::get('email_address'))->first();

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

Zend Framework - join query

I build a function
public function getBannedByLogin($commentId)
{
$sql = $this->getDbAdapter()->select()
->from(array('comments' => 'comments'), array())
->join(array('users' => 'qengine_users'),
'comments.bannedBy = users.userId',
array())
->where('commentId = ?', $commentId)
;
$row = $this->fetchRow($sql);
return $row['login'];
}
And there are problems, that does'nt work! :D
Let's I explain you. Column 'bannedBy' from comments returns id of user, who give a ban. I need to join this with table users to load a login field. Where i have mistakes?
I assume the code works in the sense of not throwing an exception. If so, your code is OK, you just specifically tell Zend_Db not to select any columns.
public function getBannedByLogin($commentId)
{
$sql = $this->getDbAdapter()->select()
->from(array('comments' => 'comments'))
->join(array('users' => 'qengine_users'),
'comments.bannedBy = users.userId')
->where('commentId = ?', $commentId)
;
$row = $this->fetchRow($sql);
return $row['login'];
}
The last argument to from() and join() functions is an array of columns you wish to select. If you pass in an empty array, no columns are selected. No argument = select everything. You can, of course, specify only the columns you need too.

Yii JSON with relations

How I can return object with all relations(ans sub objects relations?).
Now I use EJsonBehavior but it returns only first level relations, not sub related objects.
My source code:
$order = Order::model()->findByPk($_GET['id']);
echo $order->toJSON();
Yii::app()->end();
The eager loading approach retrieves the related AR instances together with the main AR instance(s). This is accomplished by using the with() method together with one of the find or findAll methods in AR. For example,
$posts=Post::model()->with('author')->findAll();
The above code will return an array of Post instances. Unlike the lazy approach, the author property in each Post instance is already populated with the related User instance before we access the property. Instead of executing a join query for each post, the eager loading approach brings back all posts together with their authors in a single join query!
We can specify multiple relationship names in the with() method and the eager loading approach will bring them back all in one shot. For example, the following code will bring back posts together with their authors and categories:
$posts=Post::model()->with('author','categories')->findAll();
We can also do nested eager loading. Instead of a list of relationship names, we pass in a hierarchical representation of relationship names to the with() method, like the following,
$posts=Post::model()->with(
'author.profile',
'author.posts',
'categories')->findAll();
The above example will bring back all posts together with their author and categories. It will also bring back each author's profile and posts.
Eager loading may also be executed by specifying the CDbCriteria::with property, like the following:
$criteria=new CDbCriteria;
$criteria->with=array(
'author.profile',
'author.posts',
'categories',
);
$posts=Post::model()->findAll($criteria);
or
$posts=Post::model()->findAll(array(
'with'=>array(
'author.profile',
'author.posts',
'categories',
)
);
I found the solution for that. you can use $row->attributes to create data
$magazines = Magazines::model()->with('articles')->findAll();
$arr = array();
$i = 0;
foreach($magazines as $mag)
{
$arr[$i] = $mag->attributes;
$arr[$i]['articles']=array();
$j=0;
foreach($mag->articles as $article){
$arr[$i]['articles'][$j]=$article->attributes;
$j++;
}
$i++;
}
print CJSON::encode(array(
'code' => 1001,
'magazines' => $arr,
));
This is the best piece of code I found after a long time search to meet this requirement.
This will work like Charm.
protected function renderJson($o) {
//header('Content-type: application/json');
// if it's an array, call getAttributesDeep for each record
if (is_array($o)) {
$data = array();
foreach ($o as $record) {
array_push($data, $this->getAttributes($record));
}
echo CJSON::encode($data);
} else {
// otherwise just do it on the passed-in object
echo CJSON::encode($this->getAttributes($o));
}
// this just prevents any other Yii code from being output
foreach (Yii::app()->log->routes as $route) {
if ($route instanceof CWebLogRoute) {
$route->enabled = false; // disable any weblogroutes
}
}
Yii::app()->end();
}
protected function getAttributes($o) {
// get the attributes and relations
$data = $o->attributes;
$relations = $o->relations();
foreach (array_keys($relations) as $r) {
// for each relation, if it has the data and it isn't nul/
if ($o->hasRelated($r) && $o->getRelated($r) != null) {
// add this to the attributes structure, recursively calling
// this function to get any of the child's relations
$data[$r] = $this->getAttributes($o->getRelated($r));
}
}
return $data;
}