Validate presence of nested attributes within a form

Viewed 8200

I have the following associations:

#models/contact.rb
class Contact < ActiveRecord::Base
  has_many :contacts_teams
  has_many :teams, through: :contacts

  accepts_nested_attributes_for :contacts_teams, allow_destroy: true
end

#models/contacts_team.rb
class ContactsTeam < ActiveRecord::Base
  belongs_to :contact
  belongs_to :team
end

#models/team.rb
class Team < ActiveRecord::Base
  has_many :contacts_team
  has_many :contacts, through: :contacts_teams
end

A contact should always have at least one associated team (which is specified in the rich join table of contacts_teams).

If the user tried to create a contact without an associated team: a validation should be thrown. If the user tries to remove all of a contact's associated teams: a validation should be thrown.

How do I do that?

I did look at the nested attributes docs. I also looked at this article and this article which are both a bit dated.

For completion: I am using the nested_form_fields gem to dynamically add new associated teams to a contact. Here is the relevant part on the form (which works, but currently not validating that at least one team was associated to the contact):

<%= f.nested_fields_for :contacts_teams do |ff| %>
  <%= ff.remove_nested_fields_link %>
  <%= ff.label :team_id %>
  <%= ff.collection_select(:team_id, Team.all, :id, :name) %>
<% end %>
<br>
<div><%= f.add_nested_fields_link :contacts_teams, "Add Team"%></div>

So when "Add Team" is not clicked then nothing gets passed through the params related to teams, so no contacts_team record gets created. But when "Add Team" is clicked and a team is selected and form submitted, something like this gets passed through the params:

"contacts_teams_attributes"=>{"0"=>{"team_id"=>"1"}}
5 Answers

Model Names: 1: approval 2: approval_sirs

Associations: 1: approval has_many :approval_sirs, :foreign_key => 'approval_id', :dependent => :destroy accepts_nested_attributes_for :approval_sirs, :allow_destroy => true 2: approval_sirs
belongs_to :approval , :foreign_key => 'approval_id'

In approvals.rb ## nested form validations validate :mandatory_field_of_demand_report_sirs

private

def mandatory_field_of_demand_report_sirs
    self.approval_sirs.each do |approval_sir|
        unless approval_sir.marked_for_destruction?
          errors.add(:base, "Demand Report Field are mandatory in SIRs' Detail") unless approval_sir.demand_report.present?
        end
    end
end
Related