我有两个模型:Project
和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
在新的/编辑Project
表单上,我有一个学科列表和每个学科的复选框,以便用户可以选择学科:
<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>
我想添加一个验证,要求至少检查一个规程。我试过但我还没弄明白。如何添加此验证?
答案 0 :(得分:16)
在答案之前的旁注,基于模型的结构,我将使用has_and_belongs_to_many而不是使用此显式链接模型,因为看起来链接模型不会添加任何有价值的内容。
无论哪种方式,答案都是一样的,即使用自定义验证。根据您是按照它们的方式使用,还是简化为has_and_belongs_to,您需要稍微区别地进行验证。
validate :has_project_disciplines
def has_project_disciplines
errors.add(:base, 'must add at least one discipline') if self.project_disciplinizations.blank?
end
或使用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
答案 1 :(得分:11)
我更喜欢更简单的方法:
class Project < ActiveRecord::Base
validates :disciplines, presence: true
end
此代码与John Naegle或Alex Peachey的代码完全相同,因为validates_presence_of
利用了blank?
方法。
答案 2 :(得分:3)
您可以编写自己的验证器
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