Adding a single field adds a lot of seconds to page generation time - laravel-backpack

I know in this case I must then customize storing/updating data. No problem in this side.
I m adding this field
$this->crud->addField([
'label' => 'Denominazione',
'type' => 'text',
'tab' => 'Cliente/Richiedente',
'name' => 'customer.name',
'wrapper' => ['class' => 'form-group col-md-6'],
'attributes' => [
'class' => 'form-control text-uppercase'
]
]);
The entity being edited is a Practice
Practice has a 1:1 relationship to Customer
public function customer()
{
return $this->hasOne(Customer::class, 'practice_id');
}
and customer has the field named name
What I'm diong works perfectly but the problem is that adding this field, bring page load time from <3 sec to >9 second
I've only 1 record in practices table and only 1 record in customers table
customer.practice_id point to practice.id and is a foreign key in the db
I think i'm doing something wrong here, and I don't know why it's adding so much time to load a single field !
Notes
I am using debug bar for laravel, so I've execution time of ALL queries. The problem is NOT a slow query.
adding field to a different tab doesn't change; removing tabs at all doesn't change execution time; removing this specific field removes 8 seconds of 9 total execution. Why ?!
I'm using latest version of backpack, 5.3.5, with also a paid Pro package
Also note I'm not using a TONS of views
With the field
Without the field

I was unable to reproduce that specific issue.
I've create a CRUD, added 2 Fields (one text and other hasOne.relation_attribute), with or without the hasOne field the load times are similar. 200ms/350ms
From the issue you described I would expect atleast for it to go to 1 second or something similar when I added the hasOne relation
The times are very similar, if I refresh the page some more times I get less loading time with the hasOne field that with only the text field.
If you use the hasOne relation in any other crud you can notice the same behavior? Or is it only in this specific CRUD?
I tried it also in our demo, specifically the MonsterCrud that has ALOT of fields and it's not optimized. Removing the hasOne fields from there has not the impact you are describing here.
If you change the field place instead of deleting, same happens ?
Cheers

I opened an issue on backpack crud to full document my timings. I found 'where' the issue is in the backpack code, but NOT WHY. And also, I've no idea on how to make it reproducible
The problem is when internally backpack try to 'guess' the default field name of a relationship.
By my knowledge, the implementation is not optimized, but has no problem, but a specific call causes 7 seconds of 'hang'
That said, I found 2 workarounds
Adding a attribute field to each field coming from a relationship
(instead of 1.) Adding in each models a public function identifiableAttribute() returning the default field name for a model, just to avoid at all the calling of that code
So
I'am not sure if it's not a strange bug of framework, backpack or php, but 2 of my coworkers, with same code, has same problem, but, we cannot reproduce in no other project, so it's of course due to a moltitude of factors we cannot understand
Is there 2 workarounds and now our code bring a full monster page on < 1 second

Related

How do I create rows without refetching related objects?

I have the opposite problem of this guy.
I have an application that used to use this pattern a lot:
$rs->create({ foo => 'bar',
status => { label => 'Active' } });
Behind the scenes DBIC will perform a SELECT to find out if the corresponding status object needs to be created, or if one with the label "Active" exists. If it does exist, its ID will be used as the value for the FK in the object I'm creating.
The thing is, the status table is almost never going to change, and there are not very many statuses, so 99.99% of the time it's basically a wasted query to the DB. We thought of using ENUMs instead, but it's very early days for the application so we are bound to have a few new statuses pop up in the first few weeks. INSERT is less of a pain in the *** than ALTER TABLE status CHANGE label label ENUM(...). Plus having them in a table means we can list the possible values easily for the UI to build dropdowns.
So now we have a bunch of get_THING_id functions, that take a THING label and return an ID. The get_THING_id functions are memoized and we do this:
$rs->create({ foo => 'bar',
status_id => get_status_id('Active') });
It doesn't feel very DBIC-y and it's awkward having to import those all over the place.
Should we bite the bullet and just use ENUMs? What do people do for this type of tiny table?
We have a ::Constants class (package) in our DBIC schema which containts constants for all those static things.
As it usually requires to adapt the schema or even application logic if the contents of such tables change, adding/changing the constants isn't an issue.

Magento filter products by custom attributes

I think I tried everything and read everything, but I'm pretty confused about filtering product collection in Magento. I created a new product attribute 'syncron_state', but I can't manage to filter the product_collection by this filter. When I try to filter by core attributes it works and that's clear.
$productsCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('sku', array('eq' => '000001'))
->setCurPage(1)->setPageSize(10)
->load();
But if I try to filter by my attribute I get nothing.
$productsCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('syncron_state', array('eq' => '1'))
->setCurPage(1)->setPageSize(10)
->load();
The syncron_state is a Yes/No Attribute, as far as I know it has an integer value in database (but i tried true/false and yes/no in filtering also).
I tried all versions of addAttributeToFilter and AddFieldToFilter.
Oh, and I'm fighting with Magento 1.7.0.0
Your collection using syncron_state as a filter should work as expected, at least for products having syncron_state set to yes.
One possible reason for not getting products would be, that you failed to add the new syncron_state attribute to the proper attribute set (which is a must).
Another possible reason would be, that you simply forgot to set the syncron_state attribute of at least one product to Yes.

How to make a field "autocomplete"?

I can't figure out how to make a field autocomplete in ATK.
I guess it has something to do with the type "reference" but still not sure.
Suppose I'm looking for a client name in a "line" type field, then the autocomplete should list me all/topXX matching names.
Scenario 1:
Once I hit [Enter] I'd need all that row from DB loaded in a form fields so I can edit the record.
I guess this requires getting the client ID first then posting to an "edit" page then calling "loadData()" method for that ID and populate fields.
Scenario 2:
I'm assignig a job request to a client. First I find the client then I could store its ID in a hidden field to be posted then.
Any advice?
TIA
I would suggest you to go with 2 forms. First form with a single field, and when field is changed it automatically reloads second form including the parameter.
You will also need an autocomplete field. Autocomplete is somewhat buggy in 4.0, but it have been polished up in 4.1 by using a technique in http://jqueryui.com/demos/autocomplete/#combobox
For use with models and controllers and also dropdown, example is here:
http://codepad.agiletoolkit.org/reloadform
Alternative example:
http://demo.atk4.com/demo.html?t=22
Since 4.1, you can also use autocomplete fields instead of reference:
$form1->addField('autocomplete','user');

coldfusion - bind a form to the database

I have a large table which inserts data into the database. The problem is when the user edits the table I have to:
run the query
use lots of lines like value="<cfoutput>getData.firstname#</cfoutput> in the input boxes.
Is there a way to bind the form input boxes to the database via a cfc or cfm file?
Many Thanks,
R
Query objects include the columnList, which is a comma-delimited list of returned columns.
If security and readability aren't an issue, you can always loop over this. However, it basically removes your opportunity to do things like locking certain columns, reduces your ability to do any validation, and means you either just label the form boxes with the column names or you find a way to store labels for each column.
You can then do an insert/update/whatever with them.
I don't recommend this, as it would be nearly impossible to secure, but it might get you where you are going.
If you are using CF 9 you can use the ORM (Object Relation Management) functionality (via CFCs)
as described in this online chapter
https://www.packtpub.com/sites/default/files/0249-chapter-4-ORM-Database-Interaction.pdf
(starting on page 6 of the pdf)
Take a look at <cfgrid>, it will be the easiest if you're editing table and it can fire 1 update per row.
For security against XSS, you should use <input value="#xmlFormat(getData.firstname)#">, minimize # of <cfoutput> tags. XmlFormat() not needed if you use <cfinput>.
If you are looking for an easy way to not have to specify all the column names in the insert query cfinsert will try to map all the form names you submit to the database column names.
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c78.html
This is indeed a very good question. I have no doubt that the answers given so far are helpful. I was faced with the same problem, only my table does not have that many fields though.
Per the docs EntityNew() the syntax shows that you can include the data when instantiating the object:
artistObj = entityNew("Artists",{FirstName="Tom",LastName="Ron"});
instead of having to instantiate and then add the data field by field. In my case all I had to do is:
artistObj = entityNew( "Artists", FORM );
EntitySave( artistObj );
ORMFlush();
NOTE
It does appear from your question that you may be running insert or update queries. When using ORM you do not need to do that. But I may be mistaken.

One (probably unbound) Access 2003 form to create multiple records

I've been recruited to work on a form for tracking specimens. Each specimen is associated with a subject; each specimen also has a particular slot in a 9 x 9 storage box. For ease of data entry, I think it would be best if the Access form mirrored the box itself (and the paper forms that will be used to enter data into Access): nine columns by nine rows, with each element consisting basically of a text box for the specimen ID. This is basically how I'd like it to look:
So the data entry person would essentially type in the box number and specimen IDs, then click "Create Records" to pop all of those records into existence (you can see some other stuff going on here, but that's not really important right now). I'm not really sure about the best way to code this, however. Right now, the best process I can think of is to: 1) run an insert query to create the box if it doesn't exist, 2) run an insert query to create the subject (person), if it doesn't exist, and 3) run an insert query for each specimen, hard-coding in its row and column (e.g. box_col = 'A', box_row = '1').
Note: the subject ID and specimen ID would both be parsed out of the ID field - it's goofy, not my idea, but that's how it's set up. I can handle that, though.
This is a certainly a kludge, but I'm not sure what else to do and most of what I've googled up hasn't been pertinent to multiple-record creation from a single form. Is there a better way to do this? Should I simply abandon the idea and go with a more traditional bound subform approach?
This could be all done in a sub form - however, I assume for simplicity (less clicks, easier user experience, and intuition) you've designed it so that the end user sees everything he /she need to enter. There is nothing wrong with doing it this way. Once the data is all entered just have a button on the form that does the multiple inserts at once.
Start at 1 and include 9 iterations each time issuing a new INSERT statement.
Once the statement has been completed I would personally put a little check mark next to each row so that if an insert succeded it would check it true, else false. You could be nifty and use a green image / red image. After it has completed the process all fields should be cleared allowing additional entry.
I don't see an issue with what you have.
FRIG. I just lost ten minutes of typing. This is why I don't care for web based forms. Although to be fair this is the first time this has happened on StackOverflow.
Do you really need to view the data later in the same format as it's entered. If they can just view regular subforms that's at least half the work as you no longer need to do updates of this form.
Also note that there is a lifetime amaximum of 768, if I recall correctly, controls per form. 9 x 9 x 2 is 162 so you'll be ok there. However if you decide to delete and recreate lots of cotrols you could be in trouble. If you do hit that limit I think saving the form under a separate name should reset the counter.
Note you can use the following construct to refer to controls and make life easier.
Me.Controls("abc" & Row & column)
For example in the After Update of the type control you could use
call InsertRecords(3, "B")
sub InsertRecords(row as integer, Column as string)
....
cboTypeValue = Me.Controls("cboTypeID" & Row & Column)
....
This could be used as some kind of native access controls only grid.
If someone would post an example of how to create custom unbound subform with row for each unbound record and a code to loop and save it to the tables would be just great.
There wouldn't be as much controls and it wouldn't have any limits by the numbers of fields on form.