laravel select where and where condition - laravel

I have this basic query i want to perform but an error keeps coming up. Probably due to my newness to laravel.
here is the code:
$userRecord = $this->where('email', $email)->where('password', $password);
echo "first name: " . $userRecord->email;
I am trying to get the user record matching the credentials where email AND password are a match. This is throwing an error:
Undefined property: Illuminate\Database\Eloquent\Builder::$email
I've checked the email and password being passed to the function, and they are holding values. what is the problem here?
Thanks,

$this->where('email', $email)->where('password', $password)
is returning a Builder object which you could use to append more where filters etc.
To get the result you need:
$userRecord = $this->where('email', $email)->where('password', $password)->first();

You either need to use first() or get() to fetch the results :
$userRecord = $this->where('email', $email)->where('password', $password)->first();
You most likely need to use first() as you want only one result returned.
If the record isn't found null will be returned. If you are building this query from inside an Eloquent class you could use self .
for example :
$userRecord = self::where('email', $email)->where('password', $password)->first();
More info here

$userRecord = Model::where([['email','=',$email],['password','=', $password]])->first();
or
$userRecord = self::where([['email','=',$email],['password','=', $password]])->first();
I`
think this condition is better then 2 where. Its
where condition array in array of where conditions;

The error is coming from $userRecord->email. You need to use the ->get() or ->first() methods when calling from the database otherwise you're only getting the Eloquent\Builder object rather than an Eloquent\Collection
The ->first() method is pretty self-explanatory, it will return the first row found. ->get() returns all the rows found
$userRecord = Model::where('email', '=', $email)->where('password', '=', $password)->get();
echo "First name: " . $userRecord->email;

After reading your previous comments, it's clear that you misunderstood the Hash::make function. Hash::make uses bcrypt hashing. By design, this means that every time you run Hash::make('password'), the result will be different (due to random salting). That's why you can't verify the password by simply checking the hashed password against the hashed input.
The proper way to validate a hash is by using:
Hash::check($passwordToCheck, $hashedPassword);
So, for example, your login function would be implemented like this:
public static function login($email, $password) {
$user = User::whereEmail($email)->first();
if ( !$user ) return null; //check if user exists
if ( Hash::check($password, $user->password) ) {
return $user;
} else return null;
}
And then you'd call it like this:
$user = User::login('email#aol.com', 'password');
if ( !$user ) echo "Invalid credentials.";
else echo "First name: $user->firstName";
I recommend reviewing the Laravel security documentation, as functions already exist in Laravel to perform this type of authorization.
Furthermore, if your custom-made hashing algorithm generates the same hash every time for a given input, it's a security risk. A good one-way hashing algorithm should use random salting.

Here is shortest way of doing it.
$userRecord = Model::where(['email'=>$email, 'password'=>$password])->first();

$userRecord = $this->where('email', $email)->where('password', $password);
in the above code , you are just requesting for Eloquent object , not requesting for the data,
$userRecord = $this->where('email', $email)->where('password', $password)->first();
so that, you can get the first data, from the given credentials by default ordering DESC with PK, in case of multiple data with the same credentials. but you have to handle the exception, in case of no matching data.
you have one more option to achieve the same.
$userRecord = $this->where('email', $email)->where('password', $password)->firstOrfail();
in the above snippets, in case of no data, it will automatically throw a 404 error.
also, you can have alternative snippets
$filter['email']=$email;
$filter['password']=$password;
$userRecord = $this->where($filter)->first();
That's it

After rigorous testing, I found out that the source of my problem is Hash::make('password'). Apparently this kept generating a different hash each time. SO I replaced this with my own hashing function (wrote previously in codeigniter) and viola! things worked well.
Thanks again for helping out :) Really appreciate it!

Related

Eloquent model update returns true but db change not reflecting

I have a model called CustomerInfo and i am trying to update it. update returns true but the changes are not reflecting on my db.
$customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail();
$result = $customerInfo->update($data);
$data varaible is a array having key value pair.
Also tried the following
$customerInfo = CustomerInfo::where('machine_name',$username)->update($data);
make sure $data variable that you want update record by its values, not be same with that record.
in this case, you don't have sql error but return of update will be zero.
Solved my questions.
Thanks Luciano.
i started eloquent manual db transaction and forgot to commit it at the end
DB::beginTransaction();//did this
$customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail();
$result = $customerInfo->update($data);
DB::Commit() //forgot to implement this part.
$result = $customerInfo->update($data);
$result variable will return only the boolean value. Try to return $customerInfo i.e.
return response()->json($customerInfo);
This will help you to find the actual problem and make sure the CustmerInfo model contains fillable properties and the $data variable contains all the information.
Try to use dd() like below to identify the issue:
dd($variable);

Is there a way to pass condition in eloquent that if key exists then don't send object from collection (in mongodb)?

I am using jenssegers/laravel-mongodb,
I have a collection segments, I don't want those objects to be send by eloquent which has key named 'unrooted' i.e. to pass a condition to check if 'unrooted' key is set in collection, so I want
$condition[' ? '] = false; // $condition unrooted exists is false.
$segments = Segment::where($condition)->get();
I know that it can be done like getting all the objects pass the condition, and then
foreach($segments as $key => $segment){
if(property_exists($segment, 'unrooted')){
unset($segments[$key]);
}
}
dd(array_values($segments->toArray());
But it is not efficient for me incase of large collection.
Thankyou for you help.
It was simple, just used mongodb docs, posting it here for future references.
$condition['$exists'] = false;
$exists does the trick.

Laravel update query use

I used this query to update the status column.
$val="1";
vehicles::where('id' , '=' , $veh_status)->update(['status' => $val]);
But when I submitted the status value doesn't change.
you can trace your query by using ->toSql() method !
try this to find whats happening in back
Not sure what the problem is there because you haven't given much info to work with, but you can check these suggestions:
Check if the column is set to be mass assignable in the model class, that is, it is in the fillable[] array.
make sure the id you pass to the where() function is valid.
Try using another function, save() which will achieve the same results you seek, like this;
// filter the vehicle
$vehicle = vehicles::where('id', '=', $veh_id)->first();
or
$vehicle = vehicles::find($veh_id);
$vehicle->status = 1;
$vehicle->save();
Lastly, I noticed your id variable you pass to the where the () function is called $veh_status "presumably - vehicle status" and not $veh_id, "presumably - vehicle id" so probably check that out.
Ref: Laravel Model Update documentation

How to get data from variable in ln laravel 5.2

My database table has name, phone, email etc.. fields. Now I store particular field data in different variable and pass them. Here is my code. I tried it from controller function. What should I do?
$var = DB::select("SELECT * FROM reg where email = '$c_email' and Password = '$c_pass' and type = '$c_type'");
$var2 = $var->name;
$var3 = $var->phone;
return redirect('farmer')->with('key', $var2)->with('key2', $var3);
You may try the given way
return view('farmer',compact('var2', 'var3'));
Here 'farmer' is your view page
http://www.easylaravelbook.com/blog/2015/03/09/passing-multiple-variables-into-a-laravel-5-view/
When you're using redirect()->with(), you're flashing data to the session. So to get this data after redirect, use session() helper:
session('key')
https://laravel.com/docs/5.3/responses#redirecting-with-flashed-session-data
use this code. if farmer is view part. or use view part name.
$var=DB::table('reg')
->where('email', $c_email)
->where('password ', $c_pass)
->where('type', $c_pass)
->select('name','phone')
->first();
return view('farmer')->with('var', $var);
get data in view part,
$name=$var->name;
$phone=$var->phone;

Preventing Doctrine's query cache in Symfony

In my Symfony/Doctrine app, I have a query that orders by RANDOM(). I call this same method several times, but it looks like the query's result is being cached.
Here's my relevant code:
$query = $table->createQuery('p')
->select('p.*, RANDOM() as rnd')
->orderBy('rnd')
->limit(1)
->useQueryCache(null)
->useResultCache(null);
$result = $query->fetchOne();
Unfortunately, the same record is returned every time, regardless of me passing null to both useQueryCache and useResultCache. I tried using false instead of null, but that didn't work either. Lastly, I also tried calling both setResultCacheLifeSpan(0) and setResultCacheLifeSpan(-1), but neither call made a difference.
Any insight on how to prevent caching since I want a different random row to be selected each time I call this method?
Edit: I also tried calling clearResultCache(), but that just ended up causing an error stating: "Result Cache driver not initialized".
Edit 2: As requested, here's the SQL generated by calling $query->getSqlQuery():
SELECT c.id AS c__id, c.name AS c__name, c.image_url AS c__image_url,
c.level AS c__level, c.created_at AS c__created_at, c.updated_at
AS c__updated_at, RANDOM() AS c__0 FROM cards c ORDER BY c__0 LIMIT 1
It turns out I'm a moron. I tried to simplify my query for this question, and in doing so, I didn't capture the true cause. I had a where() and andWhere() call, and the combination of conditions resulted in only one possible record being matched. Thanks for taking the time to respond, everyone, sorry to have wasted your time!
Doctrine also caches entities you created in the same request/script run.
For instance:
$order = new Order();
$order->save();
sleep(10); // Edit this record in de DB in another procces.
$q = new Doctrine_Query();
$result = $q->select()
->from('Order o')
->where('o.id = '.$order->id);
$order = $result->getFirst();
print_r($order->toArray());
The print_r will not contain the changes you made during the sleep.
The following code will remove that kind of memory cache:
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
$table->clear();
}
PS: Added this answer because I found this topic trying to resolve above issue.

Resources