Is there a way to validate directly such that date field 2 is after n days of date field 1?
For example:
'date_1' => 'required|date_format:"Y-m-d"',
'date_2' => 'required|date_format:"Y-m-d"|after:date_1 +5 day'
I tried something like this but it doesnt work
The after validation rule accepts date strings and they get converted using strtotime() php function. you can use carbon to play around with the date.
Assuming you are going to use this inside a class that extends FormRequest
$new_date = Carbon::parse($this->date_1)->addDays(5);
$new_date->toDateString();
and then simply concat the value to the rule
'date_2' => 'required|date_format:"Y-m-d"|after:'.$new_date
you can also create your own validation rules.
laravel docs have a pretty decent explanation on that.
Related
I have an input field that will provide me the 24 hour format time like 16:30, 18:22, 13:50 etc. So how to set migration column for this.
I read already documentation but not did not understand.
As #M Khalid Junaid has suggested, you should define a mutator for your attribute on your model to modify the value of a normal timestamp.
So firstly, you need to create the column in the migration:
$table->timestamp('your_column_name');
Then, you can create your mutator on your model just like any method. We are going to use Carbon to play around with the format. Keep in mind that the name of the mutator needs to be the camelCase of your column name:
protected function yourColumnName(): Attribute
{
return new Attribute(
get: fn ($value) => Carbon::parse($value)->format('H:i'),
);
}
I have Laravel 5.5 project. In my_table I have 2 date fields: "valid_since" and "valid_to". I need "valid_to" field was after ("valid_to" + 5 year).
I have tried:
'valid_to' => 'required|date|after:valid_since',
Also I have tried:
'valid_to' => 'required|date|after:+5 year',
This two cases was working, but not the way I want. I need something like:
'valid_to' => 'required|date|after:valid_since +5 year',
But third case doesn't work. How can I do this?
'valid_to' => ['required','date','after:'.Carbon::createFromFormat('Y-m-d', \Request::input('valid_since'))->addYear(5)]
The above approach will do what you want.
Basically in your validation for after the specific date, you will use the requested field valid_since (like you thought of) but you are going to use Carbon to actually add 5 years to it.
Try the following
'valid_to' => 'required|date|after:'.Carbon::create($request->valid_since)->add(5, 'year')->toDateString(),
Don't forge to import carbon in the controller
use Carbon\Carbon;
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 have an input with an array of entities with an ID which must be unique
I've tried this:
'authors.*.id' => 'different:authors.*.id'
But it says 'The authors.0.id and authors.0.id must be different'
So what is a right way to validate this?
You want to use distinct rule.
When working with arrays, the field under validation must not have any duplicate values.
'foo.*.id' => 'distinct'
I am trying to find records by 'created_at' date - the database column type is 'datetime' and
I am using the UI DatePicker from jQuery
my url look like this: "localhost:3000/users_supported?selected_date=2012-10-31"
So far i am doing good :) and my query in controller looks like this:
#support_histories = current_agent.support_histories.where(:created_at => Date.parse(params[:selected_date]))
How to properly extract records by 'date' only from the 'datetime' db column
I tried doing this in Rails Console, but no luck there:
sh = SupportHistory.where(:created_at => DateTime.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => Date.parse('2012-10-31'))
sh = SupportHistory.where(:created_at => DateTime.strptime('2012-10-31', '%Y-%m-%d'))
I got records if i do like mentioned below, but that's not useful to me as i am trying to find record by 'date' not by 'DateTime'
sh = SupportHistory.where(:created_at => '2012-10-31 19:49:57')
selected_date = Date.parse(params[:selected_date])
# This will look for records on the given date between 00:00:00 and 23:59:59
sh = SupportHistory.where(
:created_at => selected_date.beginning_of_day..selected_date.end_of_day)
Time Zones may be a concern you need to look into, but this should work if all your times are in the same time zone.
A simple solution I use sometimes is to cast the date(time) field as text on the database rather than parse the string into date on application side. For your case that would be:
where('CAST(created_at AS text) LIKE ?', params[:selected_date])
Might not be the most effective on the database (depending on the context you use it in) but saves a lot of pita on the application side.
I solved this problem by creating a method in model like below,
Say, my model is ticket.rb
def created_date
self.created_at.to_date
end
then I queried like this,
selected_date = Date.parse(params[:date])
Ticket.all.map{|t| t if t.created_date == selected_date}.compact
This gives me accurate results that matches with the chosen date by the user.
Your current query doesn't work because you are querying a date on a datetime column. Those are two different data types.
For a datetime column, you'll need a datetime filter. You can do this by passing a DateTime object to the where clause. However, in your case you want records for the entire day so you'll specify a range between 00:00:00 and 23:59:59.
Before Rails 5.1:
SupportHistory.where(created_at: date.beginning_of_day..date.end_of_day)
Rails 5.1 and onwards: (this will generate the exact same range using #all_day)
SupportHistory.where(created_at: date.all_day)
If you want to parse a specific datetime
SupportHistory.where("created_at>=?", DateTime.parse('10 Dec 2021 11:54:00 PST -08:00'))