Laravel problem with relation leading zero - laravel

I have come across problems with Laravel relations when couple of model ids are identical but another has leading zero and the another has not.
Product ID | Productname
-----------|------------
012345 | Product A
12345 | Product B
If those relations are loaded in the same query, only the first one will be returned and the other will not.
The database columns are strings and in the Product model I have been set the incrementing to false and cast of id attribute to string. Doesn't Laravel's eager loading take leading zeros into account?
I'm not able to change those product ids with leading zeros.
Thanks in advance!

I just run a test on a local laravel installation and I can't reproduce the problem.
Are you sure it is not a problem of the way you structure a query? Because if at any time during your program the $id variable is treated as an integer, the future conversion to string will remove the leading zero.
For example, maybe you get the id from the request:
$productId = $request->get('product_id');
At this point $productId is considered an integer, so if you use productId to query your DB, the leading zero will be removed.
You need to be sure that during the lifecycle of your request that variable is never converted to integer.
You can test the proper query using tinker, and obtaining your products manually:
Product::find('012345');
Product::find('12345');

Related

Crystal - Compare Strings that do not fully match

I am having some trouble with a query in Crystal 2008. I have two tables with columns that are loosely related, both contain addresses. One table column is just a street name while the other is a street name plus some additional info. I want to find all records where these have the same street name and only show those. Example below:
Address
AddressB
123 St
123 St, ABC City
123 St
345 St, ABC City
I have tried using a formula such as below
if({AddressB} startswith {Address}) then {AddressB} else 'ERROR'
I have also tried this with LIKE and as well as * wildcards. Nothing seems to work. I will admit I am pretty amateur-ish with SQL and crystal so formulas are a new frontier for me writing reports. Also I should note that tables are linked appropriately with inner joins.
Any help would be greatly appreciated!
This should work. Perhaps your {Address} column is padded with spaces, so try:
IF ({AddressB} startswith Trim({Address})) THEN {AddressB} ELSE 'ERROR'
Test the effect of replacing the reference to the column name with the static text value that you "think" is in that column.
If you get a different behavior, what you think is in that column is not what is actually in that column. For example, the column might contain non-printable characters. You can get rid of those using the Replace function.
If you don't get a different behavior, then show us the expression with the static text values. That would allow us to replicate the behavior and understand the situation.
Note: the problem might be in your table join logic. If you have no join condition, then all records in TableA would join to all the records in TableB. In that case, you need to place the fields in the detail section to get a proper sense of what is being compared to what. Or rethink your join logic. Perhaps you should move one table to a subreport, or a SQL Expression instead of trying to include both tables in the main report.

rails: find model objects where foreign key date within certain range

I have a model GoalAssessments with a foreign key encounter_id. The Encounter model has an encounter_date. I want to find all instances of GoalAssessment that have an encounter_date within a certain range of dates. I've tried the following join:
GoalAssessments.joins(encounter: {encounter_date: #start_date..#end_date})
This generates an active record relation without error, but then when I try to iterate over the active record relation, I get an ActiveRecord::ConfigurationError.
Any help is appreciated.
You're using joins incorrectly. The condition is expressed in the where clause. Otherwise, if you want to add the condition to the join part, you need to fully express the join part with a string or with arel. Try
GoalAssessment.joins(:encounter).
where(encounters: {encounter_date: #start_date..#end_date})

doing a where() after a get()

I'm trying to add a new feature to an existing Laravel codebase and in that codebase there's this:
$hasGAP = (new \App\Models\Policy)->where('leadID', $leadId)
->where('policystatus', '!=', 'Canceled')
->get()->where('product.name', 'GAP Insurance')->count() > 1;
So this is doing an SQL query on the table referenced by the \App\Models\Policy model. It's doing WHERE policystatus != 'Canceled' and then it's getting the result. And then it's doing a WHERE on the result? That doesn't make sense to me.
Also, product.name isn't a column in the table. Indeed, it seems like the period (.) operator would be an illegal character..
Does this code actually work and if so what is it actually doing?
The ->get() ends the query and returns the results in a collection.
The subsequent ->where(..) and ->count() are then calls on the collection.
The dot notation is widely used in Laravel for getting sub fields of arrays, objects and similar data structures (example: array_get()) and works in ->where() (on a collection) as well.
So the posted code should work. I assume the Policy belongsTo (or hasOne) a product and the dot notation is used to search by the related product name.

Laravel validation: Unique exception not functioning for one user

My validation rule is...
$rules = [];
foreach($this->request->get('email') as $key=>$value){
$rules['email.'.$key] = 'required|regex:/[a-zA-Z]+#[a-zA-Z]+(\.[a-zA-Z]+)+/|unique:admins,admin_email,'.$this->request->get('admin_id')[$key].',admin_id';
}
Basically, the rule is that it's required, the regex passes, and the email isn't already in use with the exception of if the email is in use by that particular row. However, I'm getting this error message when I run the form:
The email.0 has already been taken.
To be clear, this form has 8 different users and only the first one is giving me this problem. I did a dd() of the rules to see what was different between the validation rules that were being applied, and I didn't see any.
"email.0" => "required|regex:/[a-zA-Z]+#[a-zA-Z]+(\.[a-zA-Z]+)+/|unique:admins,admin_email,0,admin_id"
"email.1" => "required|regex:/[a-zA-Z]+#[a-zA-Z]+(\.[a-zA-Z]+)+/|unique:admins,admin_email,1,admin_id"
"email.2" => "required|regex:/[a-zA-Z]+#[a-zA-Z]+(\.[a-zA-Z]+)+/|unique:admins,admin_email,2,admin_id"
If I update email.0, I don't get this problem. I also don't get this problem with any other rows regardless of whether I update email.0 or not. I can not delete this user as there is a foreign key constraint. To be incredibly clear, the admin_id for this specific admin is 0. Or, in other words, this is how the table looks for this specific entry
admin_id|admin_email
--------+------------
0 | ab#c.d
Edit: Where does Laravel build and run the actual query? If I can do a dd() on the database log I might be able to find what my problem is (see the actual raw query).
I am obviously missing something here - any help would be greatly appreciated!
The unique rule shouldn't be as this:
unique:admins,admin_email,0,admin_id
The zero 0 refers to the value of admin_id column which should be ignored by the unique rule.
So if you have table admins as:
admin_id | admin_email
---------+-------------
1 | a#b.c
2 | b#c.d
3 | c#d.e
and you are updating where admin_email == b#c.d
Your rule should look as
unique:admins,admin_email,2,admin_id

Laravel str_random() integer alternative

I need generate a unique code with only numbers. How can I generate unique code with str_random() with only numbers in Laravel?
There's a built in php function. This will generate a random number that is 6 characters long.
mt_rand(100000, 999999);
To ensure it's unique you need to query the database. If it's already in use, try again. Make sure to clear up codes that have been used.
Edit: Also, make sure the column in the table is marked as unique. Having accidentally not-unique identifiers can be a real headache.

Resources