I would like to start a discussion on the purpose of the blank constraint now that data binding has changed in Grails 2.4 to convert incoming empty(blank) strings from request params to null. Would it be useful to catch validation errors from data not introduced via a web request? We are considering removing many of our application's blank constraints. We do have information also coming into the app from file uploads and web services.
Thanks in advance.
You're correct that the blank constraint is largely redundant since Grails 2.4 when the data is bound from a web request). However it's still necessary to validate data from other sources, e.g. a daily Quartz job that downloads data from a web service and saves it to the database. Because there's no databinding involved, blanks would not be converted to null, so the constraint is still required.
If your rule is that you don't want to allow blank values then I think it is perfectly reasonable and probably a good idea to express that as a constraint. The fact that the data binder converts blanks to null by default will help make sure blank values are not assigned when the data binder is used, but that shouldn't replace expressing that blank values are not allowed. If you leave the constraint off and there is ever a mistake in the app (or the framework, or a plugin, etc...) that causes your rule to be violated, you won't know about it.
Related
I'm using Google Data Studio to visualize results from various queries (from different tables within the same BigQuery-database).
For this reason, I created and use multiple data-sources-connectors. Each one of them has a SQL query included and makes use of an defined input parameter (which can be changed by report editors) - called "userid". It is the same id for all queries and resulting charts.
However, when I click "Manage URL parameters", I'm not allowed to use the same URL parameter for more than one data source (instead they are called ds0, ds1, ds2 etc - although they all end up being used as "userid").
If I add a data source under File - Report Settings, a new field "userid" appears, which I can alter - this will update ALL charts in the report with the very same userid (as expected). This works, but I do want to make use of an url which delivers an report with all updated queries depending on ONE userid.
Therefore, I guess I'm overseeing something - it should be possible to just use one query parameter to update the same "userid" for all queries in all data connectors? Or have I overlooked the possibility to fire multiple queries within one data source connector? Or is it expected to create a looong url full of redundant query parameters in this case?
I'm curious for your input!
Best regards :)
There does not seem to be any good solution for this.
For now the best workaround seems to be to just repeat the parameter multiple times -- it's ugly but it works. For example, use the URL parameter mapping screen to call the parameter u1, u2, etc., and then just pass all of them:
?params={"u1":"foo","u2":"foo"}
(URL encoded of course)
The ugliness is mostly for us developers: it violates our sense of DRY and clean code, and makes the URL much longer than it needs to be. However, most people don't care or know about the URL parameters so its irrelevant to them.
The bigger downside is that when the URL is distributed to clients (bookmarks, mobile apps), every time new data sources are added that require the same URL parameters, a new URL has to be distributed to clients for no good reason. A workaround for this is to build the URL dynamically via a simple redirector function.
This issue https://issuetracker.google.com/issues/180705297 is a feature request to implement this capability.
If you group the elements that you want to control with the same parameter (select and then shift G) then it will give you options to select the data source and the params box to apply to the group.
I know the partial submit is used in icefaces 1.x, singlesubmit in icefaces 2.x and the tag in icefaces 3.x.
May someone tell me what is the substantial difference between them?
thanks.
Both partialSubmit and singleSubmit does the same thing. But in different ways.
Here is a typical form scenario:
user sees a form and starts interacting. Those forms have some fields. Some of those fields are required and are necessary to process the form. Other fields are optional.
When using partialSubmit, when a user leaves a field(onblur), iceface internally makes all other fields as non required so that the overall form can be submitted. Now since all other fields are optional and only the present field that you onblurred was required, icefaces can process the form. So it does all the validation checks and changes other elements that might have been affected and renders the whole page again with new changes. But here is the thing. The other fields that were deliberately made optional by icefaces, they also have their own validation mechnanisms. So when the form is processed, those field will show errors that they are not filled, or the password field cannot be null and all that. But since the user has not engaged other fields of the form, these errors should not be triggerred. This was the drawback of partialSubmit.
In singleSubmtit, they corrected this. In here, your field is taken and is sepately validated without affecting other fields or triggering their errors.
Hope you have understood this. If not, this link will help
www.icesoft.org/wiki/display/ice/single+submit
http://www.icesoft.org/wiki/display/ICE/Using+Single+Submit
The SingleSubmit tag is a replacement by PartialSubmit, according to ICESoft information.
Cheers!
I have an ASP.NET MVC3 application which has multilingual support. Almost every word has multilingual support and at each page request I get all the words in the currently selected language from the database into a List and I use it for each Word: I hold MeaningID for each element and print out the matched one from the List. Costly approach, but better than reaching to database for every Word.
Still, I wonder if there's a data structure I can use globally throughout the project, which is only loaded from the database when the user changes the selected language. Is there a session like list structure can I use for such a purpose?
EDIT: To make things clearer I'm posting my database tables.
--Word-- --WordBase-- --Language--
ID ID ID
Text Text Name
BaseID
LanguageID
As it's seen, WordBases are meanings that Words depend on by a Language. Example data is:
--Word-- --Base-- --Language--
1;Hallo;1;1 1;Hello 1-Deutsch
2;Hello;1;2 2;Good 2-English
3;Gut; 2;1
4;Good; 2;2
Your web app is like a dictionary? I mean... your "words" are the data of your application... or are you talking about internationalization?
If it is internationalization, I think there are better ways to do it... using the tools built in. Check this: http://afana.me/post/aspnet-mvc-internationalization.aspx
If the translatable data is too large... may be you could have an hybrid approach... keeping tokens in database... and translation in resource files. Then, caching would be useful, specially if your data doesn't change very often (you can set caching for 30min... and for that time you avoid SQL queries to retrieve words in every request).
You should cache this using Cache. Then, you can manage the Cache to hold the information during the user session or by time expiration.
Take a look here: Walkthrough: Caching Application Data in ASP.NET.
As I understand, to update any object with couchdb. I have to send the whole object back since it is actually "inserting" a new revision for the same id. This is all neat and works quite well.
But then I have a problem, I'm not so sure how should I handle that. I have an object that can't be sent to my user completely. I have to hide certain informations such as password hash.
The data is sent to the client, the revision is sent too. Now when I try to update my object I have one problem. Since some data is missing, the update will erase the attributes that are missing from my user.
That said, the easiest way I have is to get the object from couchdb, check if id and rev matches. If it does match, merge the object with the missing attributes. It will work pretty well and I can support deleting attributes too.
Then using this technique, I could add my objects to a cache that will reduce the time to query frequent objects from the database. If the object can be updated, then clear the cache for that id. If the object is newer, then I'll have to handle the error or merge the object.
Is there any better "good way" to handle this problem?
edit
After thinking about it during the night, I think I found a much much better solution. Instead of having my username and password inside my profile. I'll separate the identification object from the use profile.
In other words, I'll have to split up the object as much as possible to keep things isolated... On the plus side, I can add multiple authentication for one profile without messing with the profile itself. I can return profiles and anything necessary without returning any secret object.
It will complicate a bit the logic of insertion but it should be quite easy...
Get 1 id from couchdb using the uuid api "_uuids"
Insert password authentications (username, password, profile_id) using that uuid
If succeed, insert profile using the uuid that we got at 1
If anything wrong happen, rollback and tell the users what's wrong.
Also the nice thing about this method is that I can add access_token for oauth2 using the profile id and the logic will be almost the same as password, the auth type will differ but any auth type should work almost the same.
Yeah, extracting the secret stuff from the profile documents sounds like the way to go.
The specific case I've got in mind is as follows: an AjaxFormComponentUpdatingBehavior("onchange") is added to a TextField in a form. The behavior verifies the text for certain conditions (either the model object or the form component model, doesn't matter), based on which it might display a message (or hide it, if it has already been shown).
The problem is, there are also validators added to the TextField. One of the possible (and likely) scenarios consists of the user typing in, first, a value that causes the message to be displayed by the AJAX request. If, then, he/she types in a value that doesn't pass validation, the message should disappear, but it does not.
Apparently, either the onUpdate() method for the AJAX behavior is not called at all, or I am failing in my attempts to insert a check for non-validated entries (I have tried to test for both null values and empty strings, to no avail; I have no idea what exactly Wicket's validators do to models when data is invalid).
I am wondering if someone who actually understands validators (or AJAX, actually) has any ideas on where the problem could be.
I can post edit and post code if someone tells me this is not a general issue tying validators and AJAX, but most likely a programming mistake. I still believe the former and thus I'll refrain from posting code sections, in order to keep the discussion on an API/theoretical frame.
Thanks.
When using an AjaxFormComponentUpdatingBehavior, if any of the IValidators fail their validation, onError() will be called instead of onUpdate(). Wicket will effectively prevent invalid user input from reaching the IModels in your components, so the component's ModelObject will not be changed at all. The invalid input will probably remain available by means of getInput()/getConvertedInput() (not sure if it will in an AJAX scenario, it sure is in a traditional form submission).
However, take into account that IFormValidators are not executed when using this mechanism. If you've got any, you might be interested in overriding getUpdateModel() so that AjaxFormComponentUpdatingBehavior will not bring maybe-invalid user input into your IModels, and set modelobjects manually when you're certain user input is valid.
Regarding your specific case, you could perform all the required logic in onError() (or rely on Models that will grab data from somewhere else), and just add the components that need refreshing to the AjaxRequestTarget. This is probably what's missing in your scenario.