我看到一个嵌套属性表单的奇怪错误。我有两个模型,Partys和Guests。Party has_many Guests,Guests belongs_to Party。我有一个通过Party创建Guests的表单。
我看到的错误如下:
- 当我第一次访问表单页面时,所有内容都加载了,但我无法提交数据。如果我在页面呈现后立即刷新,那么当我按下提交时,我键入的任何内容都会进入数据库。我发现,当你点击提交按钮时,它会变为活动状态,但当它不工作时,它永远不会离开
为什么在表单提交数据之前必须刷新页面?如果能帮我解开这个问题,我将不胜感激。我甚至不确定该开始拉哪根线。
party.rb
class Party < ApplicationRecord
belongs_to :event
has_many :guests, inverse_of: :party
accepts_nested_attributes_for :guests, :reject_if => proc { |attribute| attribute[:last_name].blank? }
validate :validate_nested_attributes
def validate_nested_attributes
guests.each do |guest|
errors.add(:first_name, "first name cannot be blank") if guest.first_name.blank?
errors.add(:email, "must be valid") if !email_is_valid(guest.email)
end
end
def email_is_valid(email)
email =~ /A([w+-].?)+@[a-zd-]+(.[a-z]+)*.[a-z]+z/i
end
end
guest.rb
class Guest < ApplicationRecord
belongs_to :party
belongs_to :event
end
parties_controller.rb
class PartiesController < ApplicationController
def index
end
def new
@event = Event.friendly.find(params[:event_id])
@party = @event.parties.new
10.times {@party.guests.build}
end
def create
@event = Event.friendly.find(params[:event_id])
@party = @event.parties.new(party_params)
if @party.save
redirect_to event_guests_path(@event)
else
render 'new'
end
end
private
def party_params
params.require(:party).permit(:id, :party_name, guests_attributes: [:event_id, :id, :first_name, :last_name, :email, :phone])
end
end
new.html.erb
<div class="col-sm-10 col-sm-offset-1"><h2>Create a New Invitation Party</h2></div>
<div class="form-group col-sm-10 col-sm-offset-1 well" id="guests">
<ul>
<% if @party.errors.any? %>
<% @party.errors.each do |attribute, msg| %>
<li><%= "#{attribute} #{msg}" if @party.errors[attribute].first == msg %>
<% end %>
<% end %>
<%= form_for [@event, @party] do |f| %>
</ul>
<%= render :partial => 'guest_fields', :locals => { :f => f } %>
</div>
<div class="col-sm-8 col-sm-offset-2 pull-right">
<%= f.submit "Create Party", class: "btn btn-primary pull-right", style: "margin-right: 10%;" %>
<%= link_to "Back", event_guests_path(@event), class: "btn btn-danger pull-right", style: "margin-right: 5px;" %>
</div>
<% end %>
_guest_fields.html.erb
<%= f.fields_for :guests do |ff| %>
<%= ff.hidden_field :event_id, :value => @event.id %>
<div class="row">
<div class="form-group col-sm-3">
<%= ff.text_field :first_name, placeholder: "First Name", class: "form-control" %>
</div>
<div class="form-group col-sm-3">
<%= ff.text_field :last_name, placeholder: "Last Name", class: "form-control" %>
</div>
<div class="form-group col-sm-3">
<%= ff.text_field :email, placeholder: "Email Address", class: "form-control" %>
</div>
<div class="form-group col-sm-3">
<%= ff.text_field :phone, placeholder: "Phone Number", class: "form-control" %>
</div>
<hr>
</div>
<% end %>
GET请求的Rails服务器日志
Started GET "/events/2993Alexandro/parties/new" for -.-.-.- at 2016-10-11 23:00:56 +0000
Cannot render console from -.-.-.-! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by PartiesController#new as HTML
Parameters: {"event_id"=>"2993Alexandro"}
Event Load (0.5ms) SELECT "events".* FROM "events" WHERE "events"."path" = $1 ORDER BY "events"."id" ASC LIMIT $2 [["path", "2993Alexandro"], ["LIMIT", 1]]
Rendering parties/new.html.erb within layouts/application
Rendered parties/_guest_fields.html.erb (9.7ms)
Rendered parties/new.html.erb within layouts/application (15.9ms)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 6], ["LIMIT", 1]]
Rendered layouts/_left_bar.html.erb (1.4ms)
Completed 200 OK in 180ms (Views: 98.5ms | ActiveRecord: 0.8ms)
<%= form_for [@event, @party] do |f| %>
</ul>
为什么你的开放式标签有一半在ul
里面?匹配的末端在哪里?表单是一个块级组件——它应该完全包含在外部块中——而不是一半在一个标记中,一半在另一个标签中。
我不知道这是否能解决你的问题,但它肯定会修复你的html。试试类似的东西:
<div class="col-sm-10 col-sm-offset-1"><h2>Create a New Invitation Party</h2></div>
<div class="form-group col-sm-10 col-sm-offset-1 well" id="guests">
<ul>
<% if @party.errors.any? %>
<% @party.errors.each do |attribute, msg| %>
<li><%= "#{attribute} #{msg}" if @party.errors[attribute].first == msg %>
<% end %>
<% end %>
</ul>
<%= form_for [@event, @party] do |f| %>
<%= render :partial => 'guest_fields', :locals => { :f => f } %>
<div class="col-sm-8 col-sm-offset-2 pull-right">
<%= f.submit "Create Party", class: "btn btn-primary pull-right", style: "margin-right: 10%;" %>
<%= link_to "Back", event_guests_path(@event), class: "btn btn-danger pull-right", style: "margin-right: 5px;" %>
</div>
<% end %>
</div>
试试这个,我希望我能帮助
def new
@event = Event.friendly.find(params[:event_id])
@party = @event.parties.new(party_params)
10.times {@party.guests.build}
end