好吧,对如何解决这个问题感到困惑。
我有一个表格和两个型号。这是我的表格:
<% if @booking.errors.any? %>
<% @booking.errors.full_messages.each do |msg| %>
<p class="error"><%= msg %></p>
<% end %>
<% end %>
<% if @guest.errors.any? %>
<% @guest.errors.full_messages.each do |msg| %>
<p class="error"><%= msg %></p>
<% end %>
<% end %>
<%= form_for :booking, url: bookings_path do |f| %>
<%= label_tag :email, "Guest's Email Address" %>
<%= text_field_tag :email %>
<%= f.label :nights, "Nights" %>
<%= f.text_field :nights %>
<%= f.label :nights, "People" %>
<%= f.text_field :people %>
<%= f.label :nights, "Arrival Date" %>
<%= f.text_field :arrival %>
<% end %>
如您所见,电子邮件字段不是表单构建器的一部分。如果电子邮件尚不存在,则电子邮件地址将用于创建新的访客记录。一旦我有了客人的身份证,那么也可以预订记录。
以下是我的BookingController中创建操作的代码 - 表单提交给...
...
def create
accommodation = current_user.accommodation
guest = Guest.find_or_create_by(:email => params[:email])
@booking = accommodation.bookings.new(post_params.merge(:guest_id => guest.id))
if @booking.save
flash[:success] = 'The booking has been added successfully.'
redirect_to :controller => 'bookings', :action => 'index'
else
render 'new'
end
end
...
我确实意识到这个问题不是新问题,但我无法在我的问题的任何地方找到一个好的解决方案 - 我希望能够正确设置表格(如果需要)和验证使用这两个模型的所有字段。然后我需要显示错误消息。目前,我的电子邮件在验证期间被忽略,我不知道下一步该做什么。
任何帮助都非常感激。
答案 0 :(得分:1)
在我看来,最简单的方法是在控制器本身验证电子邮件,并将任何验证错误添加到预订变量中。像这样:
def create
accommodation = current_user.accommodation
guest = Guest.find_or_create_by(:email => params[:email])
@booking = accommodation.bookings.new(post_params.merge(:guest_id => guest.id))
if @booking.save
flash[:success] = 'The booking has been added successfully.'
redirect_to :controller => 'bookings', :action => 'index'
else
<% if params[:email].blank> %>
@booking.errors.add(:email, "can't be blank.")
<% end %>
#You can do the same thing for whatever other validation errors you have
render 'new'
end
end
注意:我没有测试代码
这可能不是最好的方法,但它可以完成工作并且很容易。您可以使用accept_nested_attributes_for,但考虑到您只验证电子邮件,我觉得有点不必要。不过,如果你想以最干净的方式做到这一点,请坚持使用accept_nested_attributes_for。
修改强>
实际上,您的代码是正确的。你刚刚发了一个语法错误。您的guest虚拟机错误未显示的真正原因是您使用了局部变量而不是实例变量。试试这个:
@guest = Guest.find_or_create_by(:email => params[:email])
您的错误消息应与您已有的代码一起显示
<% if @guest.errors.any? %>
<% @guest.errors.full_messages.each do |msg| %>
<p class="error"><%= msg %></p>
<% end %>
<% end %>
编辑2
为了避免在客人电子邮件无效的情况下保存预订实例,您可以执行以下操作:
if !@guest.errors.any? && @booking.save
flash[:success] = 'The booking has been added successfully.'
redirect_to :controller => 'bookings', :action => 'index'
else
因此,如果guest虚拟机有任何错误,if语句将在执行@ booking.save语句之前终止。
答案 1 :(得分:0)
您可以尝试进行交易。如果其中一个无效,rails将执行回滚,您可以渲染错误。
关注this question代码,看看是否有帮助。