I made a unique validation in 1 field, so for example I input "pizza", while the "pizza" already exists, so it automatically doesn't work but if I input "Pizza" the letter "p" is large it still passes, how do I fix it?
so I want when validating he doesn't pay attention lowercase or uppercase.
This my code now :
$exists = Category::where(\Str::lower('name'), '=', \Str::lower(request('name')))->orderBy('name')->first();
if ($exists) {
return redirect()->route('categories.index')->with('error', 'Nama kategori sudah ada');
} else {
Category::create(request()->all());
}
\Str::lower() actually does nothing for you here since it just returns string 'name', which is then passed as first argument in Builder::where() function.
What you can do it take advantage of Builder::whereRaw() function and do something like following
Category::whereRaw('LOWER(`name`) = ?', \Str::lower(request('name')))->first()
But Eloquent build also works if you do something like (do not use = sign)
Category::whereName(request('name'))->first()
or
Category::where('name', request('name'))->first()
Related
I need to construct query using whereBetween clause, but with a twist for which i didn't find a answer applicable in my case. I need, for when from parameter isn't present to regard that as to query from beginning. If to parameter isn't present, then needs to look everything after previously mentioned parameter.
Query currently:
Vehicle::whereBetween("updated_at", [$dates->start_date, $dates->end_date])->with("something")->get();
How i wanted it to be:
Vehicle::whereBetween("updated_at", "lookup from start date if present, if not, look from beginning", "lookup to said end date if it's present, if not, look up till the end"])->with("something")->get();
I am asking, what is appropriate to put in, when parameter isn't present so it works in way i described?
Edit:
If omitted, start date, query works fine. If end date gets omitted, query return zero in best case scenario. Worst case, throws an error.
I tried putting null, empty string, false, zero(0), for end date, nothing works.
It would make more sense to not use whereBetween and simply add where clauses conditionally. You could do this with the when() method:
Vehicle::with("something")
->when($dates->start_date, function ($query, $date) {
$query->where('updated_at', '>=', $date);
})
->when($dates->end_date, function ($query, $date) {
$query->where('updated_at', '<=', $date);
})
->get();
I'm building a site with localizations using laravel. Trying to store names and texts in 3 languages using a form. I have a model for each article and another for article translations.
Using inputs for names and texts with input names like name_en, text_en, name_de, text_de etc...
But i can't figure out how to pass input values to a foreach loop in the store method in my controller.
I tried to pass (Request $request) object into foreach loop but it returns an error. Code is below:
public function store(Request $request)
{
$test = new Test;
$test->isActive = true;
$test->save();
//TRANSLATED INPUTS = name_tr,text_tr,name_en,text_en,name_de,text_de
foreach (['tr', 'en', 'de'] as $locale => $request)//OBVIOUSLY WRONG
{
$test->translateOrNew($locale)->name = $request->input('name_'.$locale);
$test->translateOrNew($locale)->text = $request->input('body_'.$locale);
}
$test->save();
dd($test);
//echo 'Created new article with some translations!';
}
Trying to get translated inputs itno database.
It is possible to do this the way you have it set up. You could use a series of if str contains, then str replace on name, and text, until you get the right language. But that's potentially a lot of work and likely pretty confusing if you have many names and texts coming from your form (which I assume you do from the need for a foreach on the incoming data).
I suggest you re-work your form slightly to return a bit more information. Consider the following as possible elements to return from the form:
name[]
text[]
language[]
Then, in your store method you can run through each of these in a number of ways, but to explain, I'll use the clearest (though not the most efficient):
Set an index:
$i = 0;
Run through all of the form's returns, and get the corresponding text and language that comes with the name (through the same index):
foreach($request->get('name') as $name){
$lang = $request['language'][$i];
$test->translateOrNew($lang)->name = $name;
$test->translateOrNew($lang)->text = $request['text'][$i];
$i ++;
}
This is almost pseudo code, and you will have to re-factor to make it work for you, but it should give you one idea on how you might do this. You will need to validate that the user provides each set (name, text, language) as complete, or the index will fail.
I want to validate a "price" field in Laravel.
The price should only contain numbers without (.) or (,) and cant start with 0 as well.
Eg
2500 // Pass
02500 // Fails
12.12 // Fails
12,12 / Fails
The rule I have now looks like this:
'price' => 'required|integer|not_in:0',
It seems to work with the example above, however I dont understand it. Why does not integer allow something like 0123 with a starting zero. I just want to make sure that my rule works as excpected and that I dont miss something
Thanks
This works for me:
'price' => 'required|numeric|gt:0',
You can format the input before sending it to the validator in your Request class.
public function formatInput()
{
$input = array_map('trim', $this->all());
$input['price'] = (int)($input['price']);
$this->replace($input);
return $this->all();
}
Then you can use
'price' => 'required|integer|min:0',
Hope this helps
if you're not sure about the rule "integer", you can use the regex expression validation as following :
'price' => 'required|regex:^[1-9][0-9]+|not_in:0',
I had some issue same way as you, and since then i always used the regex validation for this kind of requirements. Furthermore it allow you to take back the same regex if you want to make a front validation with js.
Here is the laravel function allowing to validate integers :
public function validateInteger($attribute, $value)
{
return filter_var($value, FILTER_VALIDATE_INT) !== false;
}
SO it's PHP itself that is concerned by this behavior. PHP tells us this thing about FILTER_VALIDATE_INT :
Validates value as integer, optionally from the specified range, and
converts to int on success.
No other informations are set by PHP about the "0" value, but it's known that this function doesn't consider numbers starting by "0".
Use regex rule to not allow for integer with starting 0
'price' => 'required|integer|not_in:0|regex:^[1-9][0-9]+',
I am creating an API in Laravel and using query strings to handle complex queries.
It is easy to handle queries like url/item/?color=red&age=3... to collect all items that are red and 3 years old.
But this is because these are discrete variables being queried for equality. Say for example I want to retrieve all users who registered after a certain date. How would I handle this?
I was thinking maybe:
url/item/?registered_later_than=DDMMYYYY
Is there a better way?
I'd suggest something like this:
url/item/?registered=>:DDMMYYYY
The parameter name is the name of the attribute
Right at the beginning of the parameter value is the operator
Operator and value is separated by a : (it actually can be any separation character you want)
Other examples:
url/item/?name=like:foo
url/item/?email==:foo.bar#example.com
I agree email==:foo looks a bit weird. You could also use words or abbreviations ("eq", "gt", etc) instead of operator signs.
How to parse it
$filters = Input::all();
$query = Model::newQuery();
foreach($filters as $attribute => $filter){
$parts = explode(':', $filter, 2);
$operator = $parts[0];
$value = $parts[1];
$query->where($attribute, $operator, $value);
}
I hope this gives you an idea how you could do it ;)
Not really a "better way" but you can try something like this :
url/item/?operator=lt&date=20141223
Operator can be :
lt : lesser than
gt : greater than
eq : equals to
etc.
Or whatever you want (maybe it's more readable with in full text: "greater_than", etc.). Hope I understood well your question and it will help you.
This may be a trivial question but I am wondering if Laravel recommends a certain way to check whether an Eloquent collection returned from $result = Model::where(...)->get() is empty, as well as counting the number of elements.
We are currently using !$result to detect empty result, is that sufficient? As for count($result), does it actually cover all cases, including empty result?
When using ->get() you cannot simply use any of the below:
if (empty($result)) { }
if (!$result) { }
if ($result) { }
Because if you dd($result); you'll notice an instance of Illuminate\Support\Collection is always returned, even when there are no results. Essentially what you're checking is $a = new stdClass; if ($a) { ... } which will always return true.
To determine if there are any results you can do any of the following:
if ($result->first()) { }
if (!$result->isEmpty()) { }
if ($result->count()) { }
if (count($result)) { }
You could also use ->first() instead of ->get() on the query builder which will return an instance of the first found model, or null otherwise. This is useful if you need or are expecting only one result from the database.
$result = Model::where(...)->first();
if ($result) { ... }
Notes / References
->first() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_first
isEmpty() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_isEmpty
->count() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
count($result) works because the Collection implements Countable and an internal count() method: http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
Bonus Information
The Collection and the Query Builder differences can be a bit confusing to newcomers of Laravel because the method names are often the same between the two. For that reason it can be confusing to know what one you’re working on. The Query Builder essentially builds a query until you call a method where it will execute the query and hit the database (e.g. when you call certain methods like ->all() ->first() ->lists() and others). Those methods also exist on the Collection object, which can get returned from the Query Builder if there are multiple results. If you're not sure what class you're actually working with, try doing var_dump(User::all()) and experimenting to see what classes it's actually returning (with help of get_class(...)). I highly recommend you check out the source code for the Collection class, it's pretty simple. Then check out the Query Builder and see the similarities in function names and find out when it actually hits the database.
Laravel 5.2 Collection Class
Laravel 5.2 Query Builder
I think you are looking for:
$result->isEmpty()
This is different from empty($result), which will not be true because the result will be an empty collection. Your suggestion of count($result) is also a good solution. I cannot find any reference in the docs
I agree the above approved answer. But usually I use $results->isNotEmpty() method as given below.
if($results->isNotEmpty())
{
//do something
}
It's more verbose than if(!results->isEmpty()) because sometimes we forget to add '!' in front which may result in unwanted error.
Note that this method exists from version 5.3 onwards.
There are several methods given in Laravel for checking results count/check empty/not empty:
$result->isNotEmpty(); // True if result is not empty.
$result->isEmpty(); // True if result is empty.
$result->count(); // Return count of records in result.
I think better to used
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise,
false is returned.
According to Laravel Documentation states you can use this way:
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise, false is returned.
I think you try something like
#if(!$result->isEmpty())
// $result is not empty
#else
// $result is empty
#endif
or also use
if (!$result) { }
if ($result) { }
You can do
$result = Model::where(...)->count();
to count the results.
You can also use
if ($result->isEmpty()){}
to check whether or not the result is empty.
so Laravel actually returns a collection when just using Model::all();
you don't want a collection you want an array so you can type set it.
(array)Model::all(); then you can use array_filter to return the results
$models = (array)Model::all()
$models = array_filter($models);
if(empty($models))
{
do something
}
this will also allow you to do things like count().
You can use: $counter = count($datas);
The in_array() checks if a value exists in an array.
public function isAbsolutelyEmpty($value)
{
return in_array($value, ["", "0", null, 0, 0.0], true);
}
You want to check these two cases of count().
#1
If the result contains only a single row (one record) from the database by using ->first().
if(count($result)) {
// record is exist true...
}
#2
If result contain set of multiple row (multiple records) by using ->get() or ->all().
if($result->count()) {
//record is exist true...
}