【问题标题】:How to create three records using one form? And how to show validation errors for them?如何使用一个表单创建三个记录?以及如何为他们显示验证错误?
【发布时间】:2025-12-28 07:25:11
【问题描述】:

如果我有 3 个表单和一个提交按钮,我的问题基本上是什么。

我想创建一个向每个收件人发送电子邮件的表单,然后在 free_registration_coupons 表中创建新记录。

我需要验证此表单的电子邮件。

模型 FreeRegistrationCoupon:recipient_email、token、sender_id

现在我有这个:

class FreeRegistrationCouponsController < ApplicationController
  def send_invitations
    emails = [params[:recipient_email_1], params[:recipient_email_2], params[:recipient_email_3]]
    emails.reject!{ |e| e.eql?("") }

    if emails.present?
      emails.each do |e|
        FreeRegistrationCoupon.create(:recipient_email => e, :sender_id => current_user.id)
        #MAILER
      end
      redirect_to root_path, :notice => "You just send #{emails.size} invitations!"
    else
      redirect_to(:back)
    end
  end
end


class FreeRegistrationCoupon < ActiveRecord::Base
  before_save :generate_token

  attr_accessor :recipient_email, :sender_id
  validates :recipient_email, :presence => true, :email => true

  def generate_token
    self.token = SecureRandom.hex
  end
end

这是其他控制器中的表单CarsController#confirm

<%= form_tag :controller => 'free_registration_coupons', :action => "send_invitations" do %>
  <!-- errors -->
  <%= label_tag :recipient_email_1 %>
  <%= text_field_tag :recipient_email_1 %>
  <%= label_tag :recipient_email_2 %>
  <%= text_field_tag :recipient_email_2 %>
  <%= label_tag :recipient_email_3 %>
  <%= text_field_tag :recipient_email_3 %>
  <%= submit_tag %>
<% end %>

【问题讨论】:

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


【解决方案1】:

我认为您应该使用以下方式定义表单:

<%= form_tag :controller => 'free_registration_coupons', :action => "send_invitations" do %>
  <%= @error_message %>
  <%= label_tag "recipient_email[1]" %>
  <%= text_field_tag "recipient_email[1]" %>
  <%= label_tag "recipient_email[2]" %>
  <%= text_field_tag "recipient_email[2]" %>
  <%= label_tag "recipient_email[3]" %>
  <%= text_field_tag "recipient_email[3]" %>
  <%= submit_tag %>
<% end %>

这样可以更轻松地处理控制器上的所有电子邮件地址,并且您可以跟踪这些错误以在之后显示它们:

class FreeRegistrationCouponsController < ApplicationController
  def send_invitations
    emails = params[:recipient_email]
    emails.reject!{ |param, value| value.eql?("") }
    errors = []
    if emails.any?
      emails.each do |param, value|
        validation_result = FreeRegistrationCoupon.save(:recipient_email => value, :sender_id => current_user.id)
        #MAILER
      end
      redirect_to root_path, :notice => "You just send #{emails.size} invitations!"
    else
      @error_message = "You have to include, at least, one e-mail address!"
      render :name_of_the_action_that_called_send_invitations      
    end
  end
end

我没有测试这段代码。希望对您有所帮助!

【讨论】:

  • 但是render :name_of_the_action_that_called_send_invitations 是另一个具有 id 的控制器
  • 我不太理解你,但是如果你将用户重定向到另一个控制器,与表单本身无关,感觉有些不对劲...... FreeRegistrationCouponsController 中没有新操作?跨度>