我有以下关联:
#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
contact
应始终至少拥有一个关联团队(在contacts_teams
的富联接表中指定)。
如果用户尝试创建没有关联团队的联系人:应该抛出验证。如果用户试图删除所有联系人的相关团队:应该抛出验证。
我该怎么做?
我确实查看了nested attributes文档。我还查看了this article和this article这些都有点过时了。
完成:我使用nested_form_fields
gem动态地向联系人添加新的关联团队。以下是表单上的相关部分(可行,但目前尚未验证至少有一个团队与该联系人相关联):
<%= 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>
所以当&#34;添加团队&#34;没有点击,然后没有任何东西通过与团队相关的参数传递,因此没有创建contacts_team
记录。但是当&#34;添加团队&#34;单击并选择一个团队并提交表单,这样的内容将通过参数传递:
"contacts_teams_attributes"=>{"0"=>{"team_id"=>"1"}}
答案 0 :(得分:3)
在Rails 5中,这可以使用:
完成validates :contacts_teams, :presence => true
答案 1 :(得分:2)
这会对创建和更新contact
进行验证:确保至少有一个关联的contacts_team
。目前的边缘情况会导致糟糕的用户体验。 I posted that question here。在大多数情况下,虽然这样做。
#custom validation within models/contact.rb
class Contact < ActiveRecord::Base
...
validate :at_least_one_contacts_team
private
def at_least_one_contacts_team
# when creating a new contact: making sure at least one team exists
return errors.add :base, "Must have at least one Team" unless contacts_teams.length > 0
# when updating an existing contact: Making sure that at least one team would exist
return errors.add :base, "Must have at least one Team" if contacts_teams.reject{|contacts_team| contacts_team._destroy == true}.empty?
end
end
答案 2 :(得分:1)
如果你有一个嵌套在用户模型中的Profile模型,并且你想验证嵌套模型,你可以这样写:(你还需要validates_presence_of
因为validates_associated
不验证如果用户没有任何关联的个人资料,则该个人资料)
class User < ApplicationRecord
has_one :profile
accepts_nested_attributes_for :profile
validates_presence_of :profile
validates_associated :profile
答案 3 :(得分:0)
docs建议使用reject_if并将其传递给proc:
accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? }
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
答案 4 :(得分:0)
型号名称: 1:批准 2:roving_sirs
协会:
1:批准
has_many:approval_sirs,:foreign_key =>'approval_id',:depend =>:destroy
accepts_nested_attributes_for:approval_sirs,:allow_destroy => true
2:roving_sirs
纯属_to:approval,:foreign_key =>'approval_id'
在rovings.rb中 ##嵌套表单验证 验证: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