javascript - Nested_form_fields 在验证失败时显示现有的 has_many 嵌套字段

标签 javascript ruby-on-rails ruby nested-attributes

我正在使用nested_form_fields gem 。我有以下关联,允许联系人与多个团队关联:

#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

联系人始终必须至少有一个团队。我创建了一个自定义验证,当用户创建新的联系人或更新现有的联系人时,它会检查这一点。

#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

它在大多数情况下都有效。但更新现有联系人团队时存在一种边缘情况。在这里,我正在更新联系人,它显示他们有两个现有的关联团队:

existing teams

用户单击每个团队旁边的 X 来删除它们,以便它们不再显示在页面上,然后用户单击更新以使这些更改生效:

clicks the x's next to each contact

associated teams marked for deletion and don't show

submits changes

验证正确失败,因为用户尝试删除所有关联的团队。它正确显示验证错误消息:

error message

但是,问题是表单不会重新显示现有的关联团队!这些关联尚未删除,因此它们仍应显示:

Not showing existing team associations after validation fails

更新现有联系人时验证失败后如何显示现有团队关联?

我尝试删除所有 _destroy 标志,希望通过这样做,那些关联的团队能够显示出来。不幸的是它没有达到目的:

# block run when update validation fails
else
  params[:contact][:contacts_teams_attributes].each do |k,v|
    v.delete_if{|k,v| k == "_destroy" && v == "1"}
  end
  render :edit
end

我认为该页面正在记住之前运行的nested_form_fields' javascript。因此它会记住团队被标记为要删除,因此不会渲染它们。我不知道如何重置 javascript,除非执行重定向,在这种情况下,所有验证错误将不再显示。

提前致谢!

最佳答案

这就是答案。我更改了 Contact 模型中自定义验证的名称,以便错误消息有意义:

class Contact < ActiveRecord::Base

  accepts_nested_attributes_for :contacts_teams, allow_destroy: true
  validate :at_least_one_contacts_team

  private

  def at_least_one_contacts_team
    return errors.add :A_Team, "must be present" unless contacts_teams.length > 0
    return errors.add :A_Team, "must be present" if contacts_teams.reject{|contacts_team| contacts_team._destroy == true}.empty?
  end
end

然后在 ContactsControllerupdate 操作中:

def update
  authorize @contact
  if @contact.update(contact_params)
    redirect_to(some_path), success: 'Updated Successfully.'
  else
    # This next line is what makes it work as expected for that edge case
    @contact.contacts_teams.reload if @contact.errors.keys.include?(:A_Team)
    render :edit
  end
end

关于javascript - Nested_form_fields 在验证失败时显示现有的 has_many 嵌套字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36202273/

相关文章:

javascript - 无法让 JS document.getElementById 在我的 Rails View 中工作

ruby-on-rails - 删除记录时的 SystemStackError(堆栈级别太深)

ruby - 在带有 rvm 和 ruby​​ 1.9.3 的 Mac Lion 上构建 mysql2 gem 时出错

ruby-on-rails - Rspec Ruby on Rails Controller 问题

javascript - 使用 Meteor 配置 Mandrill 失败

javascript - 使用 HTML5 canvas 和 Javascript 显示多帧 dicom 图像

ruby-on-rails - 如何将响应格式从 fast_jsonapi 格式更改为 AMS gem 响应格式

ruby-on-rails - has_many 嵌套中的自定义 RESTful 路由

javascript - Facebook 通过 FB.ui 分享

javascript - Angular Directive(指令)未被调用