【问题标题】:Rails nested models and child validationRails 嵌套模型和子验证
【发布时间】:2017-10-31 21:20:40
【问题描述】:

我有两个模型。

示例:

class Book < ActiveRecord::Base
  has_many :pages, dependent: :destroy
  accepts_nested_attributes_for :pages, allow_destroy: true
end

class Page < ActiveRecord::Base
  belongs_to :book

  validate_on_create :count_within_bounds

  LIMIT = 200

  private

  def count_within_bounds
    if self.book.pages.count >= LIMIT
      errors.add_to_base("Number of pages cannot be greater than #{LIMIT}")
    end
  end
end

现在,当通过嵌套表单更新图书时,一切正常。我可以编辑让我们说标题并添加新页面。但是,如果页面验证失败,则对图书模型所做的其他更改也不会保存。

我知道这一切都保存在一个事务中,但是有没有办法保持父级,而不必分两步手动执行,即先保存父级而不使用 pages_attributes?

【问题讨论】:

  • 工作流程是什么样的?我的意思是,你想保存这本书但仍然显示错误吗?开箱即用的 Rails 并不适合处理这种情况。
  • 正是这个。我想要的是保留对 Book 所做的所有更改,并跳过无效的孩子。
  • 在 Rails 中没有很好的方法来处理它。您必须跳过验证,然后只保存那些小于限制的页面。不过,这有点糟糕,您需要提醒用户,虽然操作成功,但它并没有保存所有数据。同样,使用 Rails 也没有简单的方法来做到这一点。我会认真考虑不同的工作流程,这样用户就不会相信某件事确实成功了。

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

您可以取消验证并执行以下操作:

<%= form_for(@book) do |f| %> 
    # book attribute stuff....

      <% if @book.pages.count < 200 %>
            <%= f.fields_for :pages, @book.pages.create do |ff| %>
            <%= ff.text_field :attribute %><br>
           <% end %>
         <% end %>
  <% end %>

现在只有少于 200 页的图书才会获得包含添加页面字段的表单。

【讨论】:

    【解决方案2】:

    如果您只想保存父类并跳过Page 子类的验证,您可以在Book 模型中使用validate 选项。

    class Book < ActiveRecord::Base
      has_many :pages, validate: false, dependent: :destroy
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 2011-07-05
      • 2012-12-12
      • 1970-01-01
      • 2012-08-29
      相关资源
      最近更新 更多