Ruby on rails 嵌套Rails 4表单访问数组

Ruby on rails 嵌套Rails 4表单访问数组,ruby-on-rails,simple-form,nested-forms,nested-attributes,Ruby On Rails,Simple Form,Nested Forms,Nested Attributes,我有一个嵌套表单,其中有3个字段重复7次。我想做一个检查,如果第一个字段组为空,那么它将停止进程并返回一个错误,要求用户填写这些字段 我已经签入,它将从控制器中的创建操作中删除任何空字段组,即模型的“reject_if:=>:all_blank”部分。但是,它删除了第一个条目,我宁愿对其进行检查。这段代码不起作用,除了尝试改进check_attendee_form方法之外,我不知道从这里可以走到哪里。任何帮助都将不胜感激 以下是相关模型: class Registration < Acti

我有一个嵌套表单,其中有3个字段重复7次。我想做一个检查,如果第一个字段组为空,那么它将停止进程并返回一个错误,要求用户填写这些字段

我已经签入,它将从控制器中的创建操作中删除任何空字段组,即模型的“reject_if:=>:all_blank”部分。但是,它删除了第一个条目,我宁愿对其进行检查。这段代码不起作用,除了尝试改进check_attendee_form方法之外,我不知道从这里可以走到哪里。任何帮助都将不胜感激

以下是相关模型:

class Registration < ActiveRecord::Base

# Database Relationships
belongs_to :event
belongs_to :user
has_many :attendees

# Form relationships
accepts_nested_attributes_for :attendees,
            :allow_destroy => true,
            :reject_if => :all_blank

class Attendee < ActiveRecord::Base

# Database relationships
belongs_to :event
belongs_to :user

delegate :event, :event_id, to: :registration

# Validations
validates :first_name, :last_name, presence: true
最后,重要的表单信息:

<%= simple_form_for [@event, @registration], :html => { :class => 'form-horizontal' } do |f| %>

<%= render 'shared/errors', object: @registration %>

<%= f.simple_fields_for :attendees, defaults: { input_html: { class: 'form-horizontal' } }  do |a| %>

<div>

<%= a.label :first_name %>:
<%= a.text_field :first_name %>
<%= error_span([:first_name]) %>
<%= a.label :last_name %>:
<%= a.text_field :last_name %>
<%= error_span([:last_name]) %>
<%= a.label :fundraising_goal %>:
<%= a.number_field :fundraising_goal, placeholder: 'No Commas' %>
<%= error_span([:fundraising_goal]) %>

如何访问此表单提交中Attenders_属性为ID[0]的第一个数组对象?

您的表单属性是嵌套哈希,您可以使用ID(如0、1等)访问Attenders


i、 e参数[registration][Attendes][0]

如果您想确保至少输入一名与会者进行注册,我相信您可以删除
检查与会者表单
方法,并将以下验证添加到registration.rb:

validate :check_minimum_attendees

def check_minimum_attendees
    errors.add(:attendees, 'must be entered') if attendees.size == 0
end

如果我是正确的,问题在于:如果条件为,则拒绝。 您可以使用Proc(或lambda)来“拒绝”任何不合适的嵌套属性

:reject_if => lambda { |e| e[:last_name].blank? && (e[:_destroy].blank? || e[:_destroy] == 'false') }
按照@keyzee的建议使用验证:

validate :check_attendees

def check_attendees
  errors.add(:attendees, 'must be entered') unless attendees.count
  attendees.each do |a|
    errors.add(:attendees, 'error message here') if condition_here
  end
end
或者在lib文件夹(lib/check_attenders_validator.rb)中创建自定义验证器:


这就完成了任务,但随后又产生了另一个问题,即在抛出错误时,它不会在控制器上重新创建:新操作。你知道如何做到这一点吗?是的,因为与会者都是空的,所以他们被撤走了。可能有更好的方法,但您可以将
7.times{@registration.attendes.build}
行添加到创建方法的
else
部分。不幸的是,该行无法正常工作。然而,我会对我们的评论投赞成票,至少让我朝着一个好的方向前进,但我没有足够的代表点来这么做。我把这个放进去,它起了作用<如果Attendes.size==0错误,则代码>定义检查\u minimum \u Attendes。将\u添加到\u blank(:Attendes)7.times{Attendes.build}否则结束并使用@keyzee建议的验证。这两种方法都不起作用。看起来你的代码是最优雅的,但它并没有达到我想达到的目的。如果我将“检查与会者”添加到注册模型(或attendee)中,并将“condition_here”设置为attendee.size==0,那么它只会跳过验证。有什么想法吗?如果您设置了“拒绝\如果”-它将在验证之前运行。在我的示例中,如果'last_name'字段为空且'u destroy'未设置为'true',它将删除所有嵌套记录每个“块”允许您使用块变量('a')验证每个嵌套记录。错误。如果a.last_name.blank,则添加(:attendeers,'last name不能为空)?我不明白代码中会是什么样子。您好,他想访问散列中的第一个元素数组。如果您希望在控制器操作中访问第一个元素数组,那么参数类似于params[registration][Attenders][0],它将返回类似{“first_name”=>,“last_name”=>,“Fundacing_goal”=>,}params[registration][Attenders][0],使用,我们可以获得第一个数组元素
:reject_if => lambda { |e| e[:last_name].blank? && (e[:_destroy].blank? || e[:_destroy] == 'false') }
validate :check_attendees

def check_attendees
  errors.add(:attendees, 'must be entered') unless attendees.count
  attendees.each do |a|
    errors.add(:attendees, 'error message here') if condition_here
  end
end
class CheckAttendeesValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << 'error_message' if condition_here
  end
end
validates :attendees, check_attendees: true