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.
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
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.
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.