验证失败后嵌套字段的茧数增加

cocoon number of nested fields increasing after validation fail

Rails4.2.1,Ruby2.2.1 宝石:simple_formcocoon

以下是具有关系的模型:

class User < ActiveRecord::Base
  has_many :galleries, dependent: :destroy
  accepts_nested_attributes_for :galleries, reject_if: :all_blank, allow_destroy: true
  validates_presence_of :name
end

class Gallery < ActiveRecord::Base
  belongs_to :user
  has_many :photos, dependent: :destroy

  accepts_nested_attributes_for :photos, reject_if: :all_blank, allow_destroy: true

  after_initialize :make_photos

  private

  def make_photos
    6.times { photos.build }
  end
end

class Photo < ActiveRecord::Base
  belongs_to :gallery

  validates :size, presence: true, numericality: { only_integer: true }
end

画廊应该正好有 6 张照片,这就是为什么我使用 after_initialize 回调来构建 6 个 photo 对象。

观看次数:

用户表单

  .form-inputs
    = f.simple_fields_for :galleries do |gallery|
      = render 'gallery_fields', f: gallery
    .links
      = link_to_add_association 'add gallery', f, :galleries

图库字段

.nested-fields
  = f.simple_fields_for :photos do |photo|
    = render 'photo_fields', f: photo
= link_to_remove_association 'remove photos', f
br

照片字段

.nested-fields
  = f.input :size

如果我在第一个输入中输入了正确的值,而在验证失败后在其他输入中输入了错误的值,则结果将是 1 个填充了正确值的输入 + 6 个空输入字段,依此类推。

如何避免?如果用户决定拥有一张,我总是需要为每个画廊制作 6 张照片。

我在 github 上推送了示例应用程序,因此您可以重现该问题 https://github.com/gabyshev/cocoon_example_increasing_number_of_fields

我认为问题是因为您有 1 个有效的关联记录,并且在对象初始化后您仍在构建 6 个记录!为避免您可以执行以下操作:

  def make_photos
    photos.size.upto(6).each { photos.build }
  end

不要使用 after_initiazlize。 Cocoon 可帮助您恰好制作 6 个画廊。你只需要使用一点 javascript:

cocoon:after-insert可以检查嵌套字段是否大于6,如果>=6,则$('.nested-fields')[1].remove();

cocoon:after-delete可以检查嵌套字段是否小于6,如果<6,则显示添加按钮。

我做过类似的事情,希望对您有所帮助:

<script>
    $('.announcements').on('cocoon:after-insert', function(e, insertedItem) {
        if ($('.nested-fields').length >= 10){
            $('.nested-fields')[1].remove();
        }
    });
    $('.announcements').on('cocoon:after-delete', function(e, insertedItem) {
        if ($('.nested-fields').length < 10){
            $('.add_fields').show();
        }
    });
    $(document).ready(function() {
        $(".add_news_button").
                data("association-insertion-method", 'after').
                data("association-insertion-node", 'this');
    });
</script>