Using a :reject_if to test uniqueness - mongoid

I've been using accepts_nested_attributes_for with embedded models for a while. For mass assignment and ryanb's nested-forms gem it is practically required. Usually, it is used like this with a lambda function to verify the parameters hash so mass assignment doesn't fail with validation errors (while still being valid) if the user doesn't place any input.
class User
include Mongoid::Document
embeds_many :comments
accepts_nested_attributes_for :comments, :reject_if => lambda { |c| c[:comment].blank? }
end
class Comment
include Mongoid::Document
embeds_in :user
fields :comment
validates_presence_of :comment
end
What that does, I assume, with the :reject_if is remove the blanks from parameters before validation. What I want to do is evaluate uniqueness as well with validates_uniqueness_of and a lambda block.
I could loop through the comments (self.comments) but I assume there is some better way of doing this. I know that this would also cause uniqueness validation errors to fail silently but I am just wondering how it could be done.

The answer was half way down in the the related column here: validates_uniqueness_of in destroyed nested model rails
The validation can be modified to not add errors but to reject erroneous data. That will pass the uniqueness validation in the embedded model while stripping duplicates (with a message that that was done).

Related

which is best to validation in serializer or in model (inside models.py save method) in django?

i am confuse on which is best to validation in serializer or in model (inside models.py save method) in django?
Serializer code
def save(self, force_insert=False, force_update=False, using=None,update_fields=None):
if self.x > self.y:
raise BadRequest(details={'message':'x should be less than y.'})
return super(xx, self).save()
or
Models code
def validate(self, attrs):
if attrs['x'] > attrs['y']:
raise BadRequest(details={'message':'x should be less than y.'})
return attrs
which is most best practical?
and how we can achieved thick model and thin view?
There is not a best method. Both methods are valid depending on your architecture.
I personally try to add any validation such as this one directly on the model. This way no matter where the data comes from, it will always get validated. For example you may wish to also apply this validation when using your django admin - if you used a serializer, the django admin request would go past this validation as it would ignore the serializer.
Working with multiple developers is also a consideration. One less familiar with the project developer may not make use of the serializer which has the validation.
Again it depends on the architecture, sometimes it makes sense to have the validation on the serializer or view. I would always consider adding it on the model first to prevent data corruption from anything hitting your model.
Here's more reading if you wish.

Adding validation to controllers in Cake 3.x

In CakePHP 3.x is it acceptable to add validation rules within a controller?
I've read http://book.cakephp.org/3.0/en/core-libraries/validation.html but it doesn't actually say where you (can / should) add your methods.
I understand that typically these go in src/Model/Table/ModelName.php. However I'm trying to validate a form which is not tied to a particular database table and doesn't need a corresponding model.
I'm familar with Cake 2.x where I would typically do this in the controller, or possibly add a model with $useTable = false. But in this case the simplest method seems to add the rules directly in the controller, but I wasn't sure whether this is bad practice. If the rules don't go in the controller where should they be put?
Context - this is a form where the user is doing a search. It requires some input and I'm trying to validate 3 fields: email, quantity and a postcode. Cake's validator has inbuilt features to do the first two but in the case of postcode I'll need to add a custom method.
Any advice appreciated.
In CakePHP 3.x is it acceptable to add validation rules within a controller?
Technically possible, but I would consider it as bad practice.
I understand that typically these go in src/Model/Table/ModelName.php. However I'm trying to validate a form which is not tied to a particular database table and doesn't need a corresponding model.
There is a whole section called "Modelless Forms" in the book that covers that use case.

Validation stages

I am validating with Cake 3 but can't get it working probably.
As the docs says there are two stages of validating:
Before you save your data you will probably want to ensure the data is correct and consistent. In CakePHP we have two stages of validation:
Before request data is converted into entities, validation rules around data types and formatting can be applied.
Before data is saved, domain or application rules can be applied. These rules help ensure that your application’s data remains consistent.
So, if I understand this right, at first validation rules are used when I pass data via newEntity and patchEntity.
After that, the application rules are used when using save or delete.
However, when I am passing data (an array) via newEntity the application rules are never used (buildRules is never called). When using newEntity without passing data, application rules are used!
So, my first question, is it right that not both rules are runned, only one (OR validation rules, OR application rules?). I would expect that first validation rules would be called to check the input, and before saving, ALSO the application rules would be called to check if the entity is valid to the applicaton.
Second question, how should I validate with my API? The actions pass their data via the newEntity method, but I want to check if (for example) the category_id belongs to the same user. Thats typical an application rule I guess?
Thank you very much ;)
Quoting CakePHP documentation:
Validation objects are intended primarily for validating user input, i.e. forms and any other posted request data.
Basically, validation is done when you use newEntity or patchEntity to check that the incoming data is consistent:
You don't have a random string where you should have a number
The user email is of correct format
Standard and confirmation passwords are equals
etc.
Validation is not done when you set field manually:
$user->email = 'not a valid email' ; // no validation check
Basically, validation rules are meant to tell the user « Hey, you did something wrong! ».
Application rules on the other end are always checked when you call save or delete, these may be used for:
Checking uniqueness of a field
Checking that a foreign key exist - There is an Group that correspond to your group_id
etc.
Your first assumption is somehow false because in the following scenario, both validation and application rules are checked:
$article = $this->Articles->newEntity($this->request->data);
$this->Articles->save($article) ;
This part of the documentation explain the difference between the two layers of validation.
Concerning your second question, you should not check that a user has the right to do something in your model, this should be done by your controller, see CakePHP book for more details.

How can I use activeadmin's has_many form builder with mongoid's embeds_many relationships?

I'm using activeadmin 0.6.1, mongoid 3.1.5, and activeadmin-mongoid 0.3.0. embeds_many relations are arguably the best thing about mongoid, reducing the need for additional queries to fetch related data.
But I can't find a good way to make them work with activeadmin's f.has_many form helper (and activeadmin-mongoid doesn't seem to provide a f.embeds_many version).
The best solution I've come up with so far is to use a has_many relation, and use mongoid-alize to denormalize the has_many fields into the parent object. But this is somewhat unwieldy, as it requires me to access them as parent.children_fields instead of parent.children, which interferes with any code that expects an array of child objects instead of an array of attribute hashes.

How to implement stack-like informations for a RoR model

i need to add to an "Event" model some information about "sub-events". For example, the Event might be a Match and a sub-event can be a goal (I need to track the striker too, and the minute), substitution or other. How is the best method to implement this? I think that is not a good solution to create a new Model for a Goal, I want that all the informations stay inside the Match model.
Maybe it can be done via "belongs to itself" association.
Look at this: Rails 3 - A model with a one to one relationship to itself - do I need belongs_to
The answer suggest using ancestry gem, or simple belongs_to association:
belongs_to :event, :foreign_key => "parent_event_id"
Also, in your model, you should add "event_type" column and put 'match', 'goal', or whatever you want here.
In my opinion it IS good solution to create Goal model, that would belongs_to a Match and a Striker and would store the information when it has happened (the minute).

Resources