Yii2 Gridview error - php

I want to display column from another table in gridview.
In my controller actionIndex:
public function actionIndex()
{
$user_id = \Yii::$app->user->identity->id;
$queryFile = PowerGen::find();
$queryFile ->select(['submitted_by','filename.file_name','filename.submitted_by'])
->joinWith('filename')//Tells Yii to use the complains relation that we define below. By default it is an inner join
->where(['filename.submitted_by' => $this->user_id]);
$dataProvider= new ActiveDataProvider([
'query' => $query,
'pagination' => false,
]);
return $this->render('index', ['dataProvider4'=>$dataProvider]);
}
In my model:
public function fileName()
{
$user_id = \Yii::$app->user->identity->id;
return $this->hasMany(Filename::className(), 'submitted_by' => $this->user_id);
}
Error is:
Error
PHP Parse Error – yii\base\ErrorException
syntax error, unexpected '=>' (T_DOUBLE_ARROW)
What is the error in the line..
Thank you

Use hasMany() like
public function fileName()
{
$user_id = \Yii::$app->user->identity->id;
return $this->hasMany(Filename::className(), ['submitted_by' => $this->user_id]);
}

First i think your function must be like this:
public function fileName()
{
return $this->hasMany(Filename::className(), ['submitted_by' => 'user_id']);
}
And your query like this:
$user_id = \Yii::$app->user->identity->id;
$queryFile = PowerGen::find();
$queryFile ->select(['submitted_by','filename.file_name','filename.submitted_by'])
->joinWith('filename')
->where(['filename.submitted_by' => $user_id]);
You are declaring the variable $user_id
$user_id = \Yii::$app->user->identity->id;
but you are not using it anywhere.

You're defining your relation in a wrong way:
Method name should be prefixed by get, like getFileName().
Second argument of hasMany() should be array with map of column names. You should not use dynamic values here or model attributes.
You should not use Yii::$app->user->identity->id or POST/GET data in your model. It breaks MVC pattern and will create problems if you will try to use this relation in console for example.
public function getFileName() {
return $this->hasMany(Filename::className(), ['submitted_by' => 'user_id']);
}

Related

How can I optimize my controller so it runs 1 query instead of 3

Below is the controller of an application I am making in Laravel 9. It runs the same SQL 3 times to get the id. Is there a way to optimize it, so it just runs once?
class ProductController extends Controller
{
public function index()
{
return view('products.index', [
'products' => product::paginate(6)->withQueryString()
]);
}
public function show($id, $name = null)
{
// Checks if product exists
if (!product::find($id)) {
return dd('Product not found');
}
$slug = Str::of(product::find($id)->name)->slug('-');
//Checks if product name is set
if (!$name || $name != $slug) {
return redirect()->route('products.show', [
'id' => $id,
'name' => $slug
]);
}
//if all above is coorect then return view
return view('products.show', [
'product' => product::find($id)
]);
}
}
Simply use variable $product.
class ProductController extends Controller {
public function index() {
return view('products.index', [
'products' => product::paginate(6)->withQueryString()
]);
}
public function show($id, $name = null) {
$product = product::find($id);
//Checks if product exists
if (!$product) {
return dd('Product not found');
}
$slug = Str::of($product->name)->slug('-');
//Checks if product name is set
if (!$name || $name != $slug) {
return redirect()->route('products.show', [
'id' => $id,
'name' => $slug
]);
}
//if all above is coorect then return view
return view('products.show', [
'product' => $product
]);
}
}
variable variable variable!
A variable in PHP is a name of memory location that holds data. In PHP, a variable is declared using $ sign followed by variable name.
The main way to store information in the middle of a PHP program is by
using a variable.
so a variable can stand for a value in all over of your code block!
try to define a variable for your query, then try to call it wherever your code need to use it:
$product = product::find($id);
In your public function show($id, $name = null) fetch the value of id into a variable first:
$productById = product::find($id);
Subsequently in the function use $productById everywhere instead of product::find($id).
(I just described what #lagbox commented in a more elaborated way.)

Laravel: How to Filter In Custom GetAttribute Before Collection

I am able to filter the Custom Get Attribute field after retrieving it to the collection. I now need to filter before using get()
Example:
For is_paid custom attribute
//is_paid
public function getIsPurchasedAttribute()
{
//Since purchased has one relation with user
return !empty($this->purchasedRelation) ? true : false;
}
I now need to retrieve User based on is_purchased like:
public function index(Request $request){
$isPaid = $request->is_paid;
$users = User::query();
if($isPaid){
$users = $users->where('is_paid', true);
}
$users = $users->paginate(10);
return view('user.index', [
'users' => $users
]);
}
If I do like this, it will return:
Column not found: 1054 Unknown column 'is_paid' in 'where clause
Yes, I can do like but I am now unable to use paginate function:
$users = User::get();
$users = $users->where('is_paid', 1);
return view('user.index', [
'users' => $users
]);
You can return all users that have purchases by using the whereHas() method.
public function index(Request $request){
$users = User::query();
if ($request->is_paid) {
$users->whereHas('purchasedRelation');
}
return view('user.index', [
'users' => $users->paginate(10),
]);
}
If anybody stumbles upon the same error and for future reference, I am posting the method I used to solve the problem:
The created custom getAttribute can be obtained only after retrieving the model.
That is using first() or find()
You cannot filter in the query collection.
So in order to filter only is_paid attribute; I first retrieved the collection of model and filtered afterwards like:
public function index(Request $request){
$isPaid = $request->is_paid;
$users = User::get();
if($isPaid){
$users = $users->where('is_paid', true);
}
$users = $users->paginate(10);
return view('user.index', [
'users' => $users
]);
}
In order to use pagination for collection, I followed Gist For Paginated Collections In Laravel

Laravel double where returning no result

I'm trying to do a double where on my table, but even if the arguments are correct I cannot view any result:
Here is my Review model:
class Reviews extends Model
{
protected $fillable=['id','product_id', 'user_id', 'rating', 'comment',
'approved', 'spam'];
public function user()
{
return $this->belongsTo(User::class);
}
public function product()
{
return $this->belongsTo(Product::class);
}
And this is my controller, where I pass the values and make the query;
a DD on the values shows them correctly:
public function storereview(Request $request){
$uid=Auth::user()->id;
$productID = $request->id;
$matchThese = ['product_id' => $productID, 'user_id' => $uid];
$result=Reviews::where($matchThese);
dd($result);
The DD of result shows this:
https://ibb.co/fSzRGH
I made a screenshot cause I can't indent this here.
What am I doing wrong? I don't understand! Thank you.
You need to use get() to actually execute the query:
$result = Reviews::where($matchThese)->get();
You need to use get() to get the result.
Reviews::where($matchThese)->get();

Laravel not saving to database

For some reason I can't save to the database. No errors, just nothing updating. I know the commands are correctly working, because returning the $user afterwards gives me the respective fields modified. But somewhere the information isn't getting put into the database.
The blade can be found here: http://pastebin.com/8bAEsjtj
The request form can be found here: http://pastebin.com/ZCD1Xvjn
This is the controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UserFormRequest;
use App\UserEdit;
use DB;
use App\Http\Requests;
class EditUserController extends Controller
{
public function index()
{
$array = UserEdit::all()->toArray();
return view('UserEntry', compact('array'));
}
public function create()
{
//
}
public function store()
{
//
}
public function show($ID)
{
try {
$array = UserEdit::findorFail($ID)->toArray();
return view('UserEdit')->with('array', $array);
} catch(\Exception $e) {
return \Redirect::route('users.index')
->withMessage('This user does not exist');
}
}
public function edit(UserEdit $user)
{
return view('EditUser', compact('user'));
}
public function update(UserFormRequest $request, UserEdit $user)
{
//$input->$request->all();
//$user->fill(Input::all());
$user->fill([
'name' => $request->get('name'),
'email' => $request->get('email'),
'First_Name' => $request->get('First_Name'),
'Last_Name' => $request->get('Last_Name')
]);
//$user->name = Input::get('name');
//$user->email = Input::get('email');
//$user->First_Name = Input::get('First_Name');
//$user->Last_Name = Input::get('Last_Name');
$user->save();
//$user->save();
// return redirect()->route('users.index')->with('message', 'Details Updated!');
return $user;
}
public function destroy($id)
{
//
}
}
Pretty sure that's all above board, so why wouldn't it work? Am I missing some detail somewhere? This is the model: http://pastebin.com/vJBzfUVu
Ok. Found the answer, there's a difference between how mysql and php handle the 'id' in a database table.
In this instance, because I've inherited the database from other devs, the id column was capitalised.
This probably made the php laravel generates throw an error as it was looking for 'id' and didn't find anything.
I didn't notice this because it didn't actually print that error, and my other code was accounting for the capitalisation.
Changing the ID to id and fixing the references in my code seems to have solved the problem.

Cannot access model from many to many relation

I am using Laravel. I am trying to relate user model and message model to many-many relation.
When I access a users message it is saying function not defined. But the that function is defined.
This is the error I am getting
Call to undefined method Illuminate\Database\Eloquent\Collection::messages()
User Model.
public function docs(){
return $this->belongsToMany('Doc');
}
public function messages(){
return $this->belongsToMany('Message');
}
Message Model.
public function users(){
return $this->belongsToMany('User');
}
I am trying to store message for selected users. This is where the error rises.
I have also set the pivot table.
Messages Controller.
public function store()
{
//
$input = Input::only('title', 'body', 'sel_users');
$msg = Input::only('title', 'body');
$sel_users = Input::only('sel_users');
$this->messageForm->validate($input);
$insert = Message::create($msg);
$id = $insert['id'];
foreach ($sel_users as $userid) {
$user = User::find($userid);
$user->messages()->attach($id);
}
return Redirect::route('messages.index');
}
Your problem is that userid in the loop is an array not single id:
foreach ($sel_users as $userid) {
$user = User::find($userid); // find() provided with array returns collection...
$user->messages()->attach($id); // .. so here you can't call messages() on that collection
}
// it works the same as:
// User::whereIn('id', $userid)->get();
This is because Input::only(...) returns array, and you must have had an array of ids in sel_users too, so:
$sel_users = Input::only('sel_users');
// $sel_users = array('sel_users' => array( id1, id2 ...) )
What you wanted here is this:
$sel_users = Input::get('sel_users');
// $sel_users = array( id1, id2 ...)
Then the rest of your code will work as expected.

Categories