How to change Laravel Auth::attempt method query? - laravel

I need to change the default Laravel query from Auth::attempt().
In the docs I saw two ways:
Pass more parameters to the Auth::attempt() method;
Create my own User provider.
The first solution not works for me, because I need to add a OR clause on the query (SELECT * FROM users WHERE email=? OR phone=?), and not an AND clause.
The second solution should be the correct one, but very complex, as I only need the retrieveByCredentials method.
Is there another way to make this?

Not sure if it's documented but you can do the following:
$givenField = '123456';
Auth::attempt([
'email' => function ($query) use ($givenField) {
$query->where('email', $givenField)
->orWhere('phone', $givenField)->from('users')->select('email');
]);
This is a bit hacky. It usually allows you to query other tables but here it's the same one

Related

Method Illuminate\Database\Eloquent\Collection::orderby does not exist

$posts = Post::all()->orderby('created_at','desc')->where('usr_id','=',session('LoggedUser'))->get();
return view('admin.profile',compact('userInfo' , 'posts'));
i am making a custom auth for a journal activity but i cant sort the content i shows this error
"Method Illuminate\Database\Eloquent\Collection::orderby does not exist. "
$posts = Post::where('usr_id','=',session('LoggedUser'))->orderby('created_at','desc')->get();
True query like that. When you take all() already query done.
Change it to:
$posts = Post::where('usr_id','=',session('LoggedUser'))->orderby('created_at','desc')->get();
you cant use all() and orderBy because all() does not allow the modification of the query.
I believe this might be because you typed orderby instead of orderBy (notice the uppercase). See laravel orderBy documentation if needed.
Plus, as mentionned by other, don't use all() if you need to do other thing (where clause, order by, etc) in you query.
Change the orderby to orderBy. This could be the reason you are getting the error.
$posts = Post::all()->orderBy('created_at', 'DESC')->where('usr_id','=',session('LoggedUser'))->get();
return view('admin.profile',compact('userInfo' , 'posts'));
Or...
If you want to get specific number of posts you can do it this way to avoid using the Post::all
$posts = Post::orderBy('created_at', 'DESC')->where('usr_id','=',session('LoggedUser'))->paginate(5);
return view('admin.profile',compact('userInfo' , 'posts'));
Yeah this is pretty confusing and just got me as well.
The actual problem isn't the capitilization typo (orderby versus orderBy) but rather the fact that you're using ->all() instead of just Model::orderBy()->...
The moment you use ->all() the object is transformed to another type of collection object and the normal methods one would expect do not exist.
In this case you should rather use sortBy().
See here.

How to select specific columns in laravel eloquent

lets say I have 7 columns in table, and I want to select only two of them, something like this
SELECT `name`,`surname` FROM `table` WHERE `id` = '1';
In laravel eloquent model it may looks like this
Table::where('id', 1)->get();
but I guess this expression will select ALL columns where id equals 1, and I want only two columns(name, surname). how to select only two columns?
You can do it like this:
Table::select('name','surname')->where('id', 1)->get();
Table::where('id', 1)->get(['name','surname']);
You can also use find() like this:
ModelName::find($id, ['name', 'surname']);
The $id variable can be an array in case you need to retrieve multiple instances of the model.
By using all() method we can select particular columns from table like as shown below.
ModelName::all('column1', 'column2', 'column3');
Note: Laravel 5.4
You first need to create a Model, that represent that Table and then use the below Eloquent way to fetch the data of only 2 fields.
Model::where('id', 1)
->pluck('name', 'surname')
->all();
Also Model::all(['id'])->toArray() it will only fetch id as array.
Get value of one column:
Table_Name::find($id)->column_name;
you can use this method with where clause:
Table_Name::where('id',$id)->first()->column_name;
or use this method for bypass PhpStorm "Method where not found in App\Models":
Table_Name::query()->where('id','=',$id)->first()->column_name;
in query builder:
DB::table('table_names')->find($id)->column_name;
with where cluase:
DB::table('table_names')->where('id',$id)->first()->column_name;
or
DB::table('table_names')->where('id',$id)->first('column_name');
last method result is array
You can use get() as well as all()
ModelName::where('a', 1)->get(['column1','column2']);
From laravel 5.3 only using get() method you can get specific columns of your table:
YouModelName::get(['id', 'name']);
Or from laravel 5.4 you can also use all() method for getting the fields of your choice:
YourModelName::all('id', 'name');
with both of above method get() or all() you can also use where() but syntax is different for both:
Model::all()
YourModelName::all('id', 'name')->where('id',1);
Model::get()
YourModelName::where('id',1)->get(['id', 'name']);
To get the result of specific column from table,we have to specify the column name.
Use following code : -
$result = DB::Table('table_name')->select('column1','column2')->where('id',1)->get();
for example -
$result = DB::Table('Student')->select('subject','class')->where('id',1)->get();
use App\Table;
// ...
Table::where('id',1)->get('name','surname');
if no where
Table::all('name','surname');
If you want to get a single value from Database
Model::where('id', 1)->value('name');
Also you can use pluck.
Model::where('id',1)->pluck('column1', 'column2');
You can use Table::select ('name', 'surname')->where ('id', 1)->get ().
Keep in mind that when selecting for only certain fields, you will have to make another query if you end up accessing those other fields later in the request (that may be obvious, just wanted to include that caveat). Including the id field is usually a good idea so laravel knows how to write back any updates you do to the model instance.
You can get it like
`PostModel::where('post_status', 'publish')->get(['title', 'content', 'slug', 'image_url']`)
link
you can also used findOrFail() method here it's good to used
if the exception is not caught, a 404 HTTP response is automatically sent back to the user. It is not necessary to write explicit checks to return 404 responses when using these method not give a 500 error..
ModelName::findOrFail($id, ['firstName', 'lastName']);
While most common approach is to use Model::select,
it can cause rendering out all attributes defined with accessor methods within model classes. So if you define attribute in your model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the user's first name.
*
* #param string $value
* #return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
And then use:
TableName::select('username')->where('id', 1)->get();
It will output collection with both first_name and username, rather than only username.
Better use pluck(), solo or optionally in combination with select - if you want specific columns.
TableName::select('username')->where('id', 1)->pluck('username');
or
TableName::where('id', 1)->pluck('username'); //that would return collection consisting of only username values
Also, optionally, use ->toArray() to convert collection object into array.
If you want to get single row and from the that row single column, one line code to get the value of the specific column is to use find() method alongside specifying of the column that you want to retrieve it.
Here is sample code:
ModelName::find($id_of_the_record, ['column_name'])->toArray()['column_name'];
If you need to get one column calling pluck directly on a model is the most performant way to retrieve a single column from all models in Laravel.
Calling get or all before pluck will read all models into memory before plucking the value.
Users::pluck('email');
->get() much like ->all() (and ->first() etc..) can take the fields you want to bring back as parameters;
->get/all(['column1','column2'])
Would bring back the collection but only with column1 and column2
You can use the below query:
Table('table')->select('name','surname')->where('id',1)->get();
If you wanted to get the value of a single column like 'name', you could also use the following:
Table::where('id', 1)->first(['name'])->name;
For getting multiple columns (returns collection) :
Model::select('name','surname')->where('id', 1)->get();
If you want to get columns as array use the below code:
Model::select('name','surname')->where('id', 1)->get()->toArray();
If you want to get a single column try this:
Model::where('id', 1)->first(['column_name'])->column_name;

How to add dynamic 'where' to eloquent ORM with() relation

I'm, trying to do something like this:
$verfuegbarkeiten = Verfuegbarkeit::verfuegbar()->with('product', 'producer', 'producer.user', 'producer.user.ort')->where('product.kategorie_id', '=', $_GET['kat'])->get()->toArray();
I want to use a 'where' clause so i can only get the results where the 'product's attribute 'kategorie_id' matches the GET parameter. How can I 'where' on a relation? It's really important to me that this value can be dynamic, so writing a fix function in the related Model won't be a good solution.
Every hint appreciated
You want whereHas(), documentation here: https://laravel.com/docs/5.2/eloquent-relationships#querying-relations
For your example, that would mean something like this:
$kat = $_GET['kat'];
$verfuegbarkeiten = Verfuegbarkeit::verfuegbar()
->with('product', 'producer', 'producer.user', 'producer.user.ort')
->whereHas('product', function($query) use ($kat) {
$query->where('kat', $kat);
})
->get()
->toArray();
Although I might add that using $_GET is generally discouraged in Laravel.

Saving a model with multiple foreign keys in Laravel 4

I understand that in order to save a foreign key, one should use the related model and the associate() function, but is it really worth the trouble of going through this
$user = new User([
'name' => Input::get('name'),
'email' => Input::get('email')
]);
$language = Language::find(Input::get('language_id');
$gender = Gender::find(Input::get('gender_id');
$city = City::find(Input::get('city_id');
$user->language()->associate($language);
$user->gender()->associate($gender);
$user->city()->associate($city);
$user->save();
when one can simply do this?
User::create(Input::all());
I feel like I'm missing something here, maybe there's an even simpler and cleaner way to handle foreign keys in controllers (and views)?
You can use push() method instead which would allow you to push to related models.
This link should answer your query.
Eloquent push() and save() difference
I really don't see anything wrong at all with doing User::create(Input::all());.
Obviously you'd want some validation, but it's doing the same thing.
I think the associate() method is more useful for the inverse of your situation.
For example, say you had a form which a user could fill out to add their city to your app, and upon doing so, they should automatically be assigned to that city.
$city = City::create(Input::all()); would only achieve the first half of your requirements because the user has not yet been attached as city does not have a user_id column.
You'd then need to do something like $city->user()->associate(User::find(Auth::user()->id));

Laravel 4: making a combination of values/columns unique

I'm importing a bunch of csv entries in my database with Laravel 4.
I can't really point at one column that has to be unique, it's a combination of 5 columns that makes it unique. However: how does one define this in Laravel?
Option 1: schema builder
You can use the $table->unique('email') method, but that only seems to allow one column, not a combination of columns.
Option 2: Validation
Less preferable, but I could validate the model before inserting it. However, again, using 'unique:[table]' validation rules, it will return an error when just one of the column values isn't unique, not a combination of them.
Can anyone tell me how I should go about this?
I'm sure I'm missing something, but I could use a push in the right direction :-)
Thanks,
Dieter
You can combine:
$table->unique( array('email','name') );
And pretty much everything in Laravel will accept arrays to do whatever you need to with 'more than one'.
Use Schema Builder's unique() method to define your data model, as Antonio mentioned.
Additionally, if you want to use validation on your model, consider my custom Validator rule for multiple UNIQUE indexes: https://github.com/felixkiss/uniquewith-validator
You can also do this;
$table->unique(["column1", "column2"], 'uq_columns');
Which means that you will have a unique column combination of all the columns i.e. column1 and column2
I know this question is for Laravel 4, but I just came across this on searches and found a solution for Laravel >= 5.3
Here it is:
Of course, the migration may look something like
$table->unique( array('email','name') );
Then to validate this, you do not need to use custom rules, just advanced rules:
'email' => Rule::unique('users')->where(function ($query) use ($request) {
return $query->where('name', $request->name);
}),
Of course, you may want to validate name before of this. The name should be required so that you may finish with something like this:
'name' => 'required|max:255',
'email' => Rule::unique('users')->where(function ($query) use ($request) {
return $query->where('name', $request->name);
}),
I hope it helps.
You can try this
$table->string("name");
$table->string("email")->unique("name")

Resources