I have two models: Project
and ProjectDiscipline
:
class Project < ActiveRecord::Base
has_many :project_disciplinizations, :dependent => :destroy
has_many :project_disciplines, through: :project_disciplinizations
attr_accessible :project_discipline_ids
attr_accessible :project_disciplines_attributes
accepts_nested_attributes_for :project_disciplines, :reject_if => proc { |attributes| attributes['name'].blank? }
end
class ProjectDiscipline < ActiveRecord::Base
attr_accessible :name
has_many :project_disciplinizations, :dependent => :destroy
has_many :projects, through: :project_disciplinizations
end
class ProjectDisciplinization < ActiveRecord::Base
attr_accessible :project_discipline_id, :project_id
belongs_to :project_discipline
belongs_to :project
end
On the new/edit Project
form, I have a list of disciplines and a check box for each one of them so users can pick disciplines:
<div class="control-group">
<label class="control-label">Check disciplines that apply</label>
<div class="controls">
<%= f.collection_check_boxes(:project_discipline_ids, ProjectDiscipline.order('name'), :id, :name, {}, {:class => 'checkbox'}) {|input| input.label(:class => 'checkbox') { input.check_box + input.text }} %>
<p class="help-block">You must choose at least one discipline.</p>
</div>
</div>
I want to add a validation to require that at least one discipline is checked. I've tried but I haven't figured out yet. How can I add this validation?
Side note before the answer, based on the structure of your models I would use has_and_belongs_to_many instead of using this explicit linking model since it appears the linking model doesn't add anything of value.
Either way though, the answer is the same, which is to use a custom validation. Depending on whether you go with things the way they are or simplify to a has_and_belongs_to many you'll want to validate slightly differently.
validate :has_project_disciplines
def has_project_disciplines
errors.add(:base, 'must add at least one discipline') if self.project_disciplinizations.blank?
end
or with has_and_belongs_to_many
validate :has_project_disciplines
def has_project_disciplines
errors.add(:base, 'must add at least one discipline') if self.project_disciplines.blank?
end
I prefer simpler approach:
class Project < ActiveRecord::Base
validates :disciplines, presence: true
end
This code do absolutely the same as code by John Naegle or Alex Peachey, because of validates_presence_of
exploit blank?
method too.
You can write your own validator
class Project < ActiveRecord::Base
validate :at_least_one_discipline
private
def at_least_one_discipline
# Check that at least one exists after items have been de-selected
unless disciplines.detect {|d| !d.marked_for_destruction? }
errors.add(:disciplines, "must have at least one discipline")
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With