Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails嵌套属性:至少需要两条记录_Ruby On Rails_Validation_Activerecord_Associations - Fatal编程技术网

Ruby on rails Rails嵌套属性:至少需要两条记录

Ruby on rails Rails嵌套属性:至少需要两条记录,ruby-on-rails,validation,activerecord,associations,Ruby On Rails,Validation,Activerecord,Associations,我如何使提交产品至少需要两个选项记录 class Product < ActiveRecord::Base belongs_to :user has_many :options, :dependent => :destroy accepts_nested_attributes_for :options, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.bla

我如何使提交产品至少需要两个选项记录

class Product < ActiveRecord::Base
  belongs_to :user
  has_many :options, :dependent => :destroy
  accepts_nested_attributes_for :options, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
  validates_presence_of :user_id, :created_at
  validates :description, :presence => true, :length => {:minimum => 0, :maximum => 500}
end

class Option < ActiveRecord::Base
  belongs_to :product
  validates :name, :length => {:minimum => 0, :maximum => 60}                  
end
类产品:销毁
接受_嵌套的_属性_for:options、:allow_destroy=>:true、:reject_if=>proc{{attrs | attrs.all?{k,v | v.blank?}
验证是否存在:user\u id、:created\u at
验证:description,:presence=>true,:length=>0,:max=>500}
结束
类选项0,:max=>60}
结束
class Product
关于karmajunkie的一个考虑答案:我会使用
大小
而不是
计数
,因为如果某些构建(未保存)的嵌套对象有错误,则不会考虑它(它还不在数据库中)

类产品
如果您的表单允许删除记录,则
.size
将不起作用,因为它包含标记为销毁的记录

我的解决办法是:

validate :require_two_options

private
 def require_two_options
    i = 0
    product_options.each do |option|
      i += 1 unless option.marked_for_destruction?
    end
    errors.add(:base, "You must provide at least two option") if i < 2
 end
验证:需要两个选项
私有的
def需要两个选项
i=0
产品选项。每个do选项|
i+=1,除非选项标记为要销毁?
结束
错误。如果i<2,则添加(:base,“您必须至少提供两个选项”)
结束

整洁的代码,用Rails 5测试:

class Product < ActiveRecord::Base
  OPTIONS_SIZE_MIN = 2
  validate :require_two_options

  private

  def options_count_valid?
    options.reject(&:marked_for_destruction?).size >= OPTIONS_SIZE_MIN
  end

  def require_two_options
    errors.add(:base, 'You must provide at least two options') unless options_count_valid?
  end
end
类产品=选项大小最小值
结束
def需要两个选项
错误。添加(:base,“您必须至少提供两个选项”),除非选项\u count\u有效?
结束
结束

使用自定义验证应该非常简单。类似于
self.errors.add_to_base(“需要两个选项”),除非self.options.length>=2
如果使用
接受
的嵌套的_属性_,并使用
允许_销毁:true
则必须使用标记的_进行_销毁?与子项关联以查找子项的确切长度,因为从表单提交时可能会有一些对象被标记为
\u destroy:true
,以便在保存对象后销毁。长度、大小和计数都不适合这种情况。这个链接有完美的答案。add_to_base(msg)已被弃用,请使用Errors#add(:base,msg)insteadoptions.count将生成SQL count查询以查找您拥有的选项数。如果您的选项在内存中,但未保存在数据库中,则会给出意外的答案,因为它们不会包含在计数中。在<代码>的应答调用中被替换。计数< /代码> <代码> >大小<代码> ..按您所说的大小来考虑,即使它不在数据库中也可以考虑。<代码>。code>.size绝对是一条路。+1注意标记为要销毁的记录的好处。但是,获取
i
的更简洁的方法可能是
i=product_options.reject{| option | option.marked_for_destruction?}.size
validate :require_two_options

private
 def require_two_options
    i = 0
    product_options.each do |option|
      i += 1 unless option.marked_for_destruction?
    end
    errors.add(:base, "You must provide at least two option") if i < 2
 end
class Product < ActiveRecord::Base
  OPTIONS_SIZE_MIN = 2
  validate :require_two_options

  private

  def options_count_valid?
    options.reject(&:marked_for_destruction?).size >= OPTIONS_SIZE_MIN
  end

  def require_two_options
    errors.add(:base, 'You must provide at least two options') unless options_count_valid?
  end
end