I think I have duplication in validation of an attribute since I am getting the same validation error twice on email field.
I suspect the some gems may enforce the same validations.
Is there a way to list (in console) the validations on a certain model/ attribute and to see where they are listed?
You can get a list of validators on an attribute with
Model.validators_on(:attribute)
or even the entire list of validators for a model with:
Model.validators
Related
Thank you for answering my previous questions and I appreciate the effort put in by you in developing Moqui.
In the field tag there is an attribute of validate-parameter so could please elaborate the use of it and how to use that attribute. Thanks in advance :-)
To be specific, it sounds like you are looking at the XML Form field element (form-list.field, form-single.field).
A form field can be validated based on the validation settings in a service parameter (there are many validation options there) or an entity field (just a couple validation options there). This is done automatically when a form submits to a transition that has a single service-call element (i.e. not an actions element), and these attributes are populated automatically. You can also specify manually which service/parameter or entity/field to use for validation.
This is all part of the support in the framework to do client side validation with JavaScript using server-side validation settings. Note that the validations are also done on the server, but you don't have to define/implement them twice.
For example, I recently added 'address' fields to my user model. They are being validated by presence. So now, when I went to update a different attribute, email for example, I can't save the user because it has invalid fields (the address is still blank).
Do you just have to migrate the data with blank strings or something?
What is the Rails way to handle this?
One way to handle this is to populate the new field in the migration which creates it. That way, you're ensuring that everything in the database is valid according to the model. The guide has some pointers on doing this - there are a couple of gotchas.
Another way is by specifying that the validation only runs on creation, not on updates, with the :on option. That might look like:
validates :address, :presence => true, :on => :create
That way, any new user has to have the address set, but you're still able to edit other attributes on existing users.
I suggest you do the migration every time you add new fields and put validations on them.
It would keep the data integrity and consistency.
If you really want to do a trick, adding conditions on validation, putting "validate: false" conditionally when you do save, adding blank value for address fields when you modify an existing records all are tricks you can use.
I also suggest that when you add address, create a address model and share it among other models which need it, instead of only adding fields into the models. That would make your validation more flexible.
I need to validate user email input from the site. Of course there is django.core.validation. However is not it easier to just use jquery validation plugin without sending POST data before all fields are valid? Or it is just better to validate threw views? Why?
This is a design decision that you can choose to make. If you need the real-time validation of your fields, then jquery-validation is the way to go.
However, if you want the validation to be done on a postback, you'll be better off using Django's form validation to get the job done.
If you do decide to do the validation on the postback, all of you have to do is use the EmailField and django will take care of the rest.
Back-end: I have a model (User) that has_many of another model (ContactPreference).
Front-end: An interface allowing the user to reorder, add, and delete contact preferences for a particular user.
I'd like to let the user commit all their changes all at once with a single form submit. The way I'm doing this now is with allows_nested_attributes_for :contact_preferences in the User model, and naively POSTing the attributes of the edited preferences list. It works just fine except for a glaring bug: If a user deletes a contact preference, the ID simply isn't sent, and the preference doesn't get deleted from the DB.
allows_nested_attributes_for has support for deleting objects from the collection, but it requires the client to keep track of what IDs were deleted and pass a '_destroy' => 1 parameter. This is messy logic that I'd rather avoid; I just want objects deleted unless they are explicitly included in the parameters. allows_nested_attributes_for doesn't support this behavior as far as I can tell, so I'm looking to implement my own solution.
What's the most efficient (in terms of database access) way to do this kind of update? Do I delete everything and rebuild the list from scratch? Do I load the association and pick out objects that aren't explicitly included? Perhaps there's some clever ActiveRecord magic I can use?
My personal feeling is that doing this using the :destroy => 1 flag set a lot less messy than the alternative. The alternative would be loading the association on the server, comparing the incoming parameters, figuring out which records are missing, then deleting the missing ones and updating the remaining ones. That's a lot of extra logic, DB operations, and worst of all, you'll have to hand-rework the accepts_nested_attributes_for which is a non-trivial feat.
HTML give you a little trick/hack to accomplish this without JS. Add a checkbox to each record with name :destroy. Use the high-level form helpers, e.g. check_box, not check_box_tag (which requires a lot of things to get right manually), or a higher level form helper such as the simple_form gem.
If the flag is not checked, then HTML won't submit anything, and the record stays. If the flag is checked, HTML will submit the :destroy flag, and it will be deleted with the built-in server-side mechanisms out of the box.
You didn't say much about your front-end code; it sounds like you have a bunch of JS on there. You probably hide the record when the user "removes" it, you can simply add the destroy flag programmatically in that case, if you don't want to use the check box method above. This will be a lot simpler and less error prone than trying to second-guess the backend behavior.
I'm coming from Asp.Net MVC world and I'm confused how to approach Rails 3 forms from model perspective.
In Asp.Net MVC it is a bad practice to bind to business model forms in templates. The proper approach is to create a class for each form, create properties which are only needed in form and attach validation attributes to them. Then in code check for ModelState.IsValid and assign values from form model to business model. This leads to separation of concepts and also prevents properties hijacking (when hackers might post additional values together with proper values and change business model properties in his cruel way).
From all tutorials and books I've read there is no seperation of this concept in Rails world - you put validation in your business model and you bind your model to the form in the template.
Is it the right approach in Rails 3 and I should follow it? Or I should follow Asp .Net MVC approach and create a separate model with validation just for forms?
In rails, updates of models generally happen via mass-assignment. For example, a form posts a ton of attributes to your update action, your update action calls:
Model.update_attributes(params[:model])
and all the values in the passed hash are updated on the model. The problem then is what happens if a hacker adds
params[:model][:users_attributes][:email] = 'hacker#example.com'`
and updates the model's associated user's email address?
In Asp.Net MVC it seems like you simply don't allow this in the form template and the value can never get to your models, but in rails this is not the way things are done (correct me if I am misunderstanding Asp.Net MVC). In Rails, everything in a model (by default) can be mass-assigned, and so your fear is warranted.
In the link I supplied, you can see "For a normal user account, for example, you only want login and password to be editable by a user. It should not be possible to change the status attribute through mass assignment."
class User < ActiveRecord::Base
attr_accessible :login, :password
end
This means any other properties must be set manually and the object saved, thus preventing the same type of property-hijacking that Asp.Net's form templates protect against. In Rails, anything that should be mass-assignable should be in your attr_accessible and then ActiveRecord is the gatekeeper. No matter how your forms are written or what a hacker does to their HTML, those attributes can only be updated explicitly by your code, not by Rails' behind-the-scenes stuff.