how can i validate the nested attributes field in

2019-04-17 17:10发布

问题:

I have two models

class Information < ActiveRecord::Base
  belongs_to :study
  validates_presence_of :email
end

and

class Study < ActiveRecord::Base
  has_many :informations
  accepts_nested_attributes_for :informations
end

I show up a form of study which contains few fields for the informations and i want to validate presence of those fields. Only on validation success i wanted to save the study field values as well and i wanted to show errors if the validation fails. How can i do this? Thanks in advance.

回答1:

You write validations in the models that you require, as normal. So if you need to validate presence of field foo in the Information class you'd just write validates_presence_of :foo in that class. Likewise validations for Study fields just go in the Study class. With nested attributes, when you update a Study instance from a params hash that contains nested attributes, it'll update the Information instance(s) too, running validations in passing. That's what the accepts_nested_attributes_for call is doing - it's giving "permission" for the appropriate bits of a params hash to be used in this way.

You can use reject_if to only reject new nested records should they fail to meet criteria. So I might let someone create a Study and only create one or more nested Information instances associated with that Study if they'd filled in field(s) in the form, but if they left them blank, the nested stuff wouldn't be created and saved (so you don't get pointless blank associated records). The Study would still be saved. For example:

accepts_nested_attributes_for(
  :informations,
  reject_if: proc() { | attrs | attrs[ 'title' ] .blank? }
)

This and more is covered in the API documentation here:

  • http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Beware that nested fields are intended for existing records only. If you were creating a new Study instance in a new/create action with no Information instances associated, you won't see any nested form fields for your Information class at all - when you might be expecting just one, for a blank new item. This can be very confusing if you aren't ready for it! You'll need to manually add a new Information instance to your Study instance in the controller or similar for the 'new' and 'create' actions, e.g. using before_filter :create_blank_object, only: [ :new, :create ], with, say:

def create_blank_object
  @study = Study.new
  @study.informations << Information.new
end


回答2:

you can use validates_presence validation available in rails other wise you can write before_create or before_save callback method. write validation logic inside the before_create or before_save callback method.



回答3:

Check out the API Doc for validates_associated:

Validates whether the associated object or objects are all valid. Works with any kind of association.

If you call a method on the parent object which runs validations (e.g. save), the validation on the associated objects will be called as well.