我需要在我正在处理的作业中使用嵌套表单,因为我的嵌套表单属性不会提交给数据库而被卡住了。
这是我的控制器的样子
def new
@booking = Booking.new
params[:no_of_passengers].to_i.times { @booking.passengers.build }
end
def create
@booking = Booking.new(booking_params)
respond_to do |format|
if @booking.save
format.html { redirect_to '/booking_confirmed', notice: 'Booking was successfully created.' }
format.json { render :show, status: :created, location: @booking }
else
format.html { render :new }
format.json { render json: @booking.errors, status: :unprocessable_entity }
end
end
end
private
def booking_params
params.permit(
:airline, :origin, :destination, :departure_date, :departure_time, :arrival_date,
:arrival_time, :flight_id, :price, :no_of_passengers, :user_id, :booking,
passenger_attributes: [
:id,:booking_id, :name, :email,:done,:_destroy
]
)
end
这是模型之间的关联
class Booking < ActiveRecord::Base
has_many :passengers
accepts_nested_attributes_for :passengers, reject_if: lambda { |attributes| attributes['name'].blank? }
end
class Passenger < ActiveRecord::Base
belongs_to :bookings
end
这是表格
<%= form_for @booking do |b| %>
<%= b.fields_for :passengers do |p| %>
<%= p.text_field :name, placeholder: "Passenger Name" %>
<%= p.text_field :email, placeholder: "Passenger Email" %>
<% end %>
<% end %>
我在rails控制台中使用Passenger.all
检查了乘客桌,但没有返回任何内容。
我做错了什么?
答案 0 :(得分:0)
在与sunnyk进行配对后,我能够看到错误。
第一个错误是我的class Passenger
有belongs_to :bookings
而不是belongs_to :booking
。这是一个常见的错误。这些类之间的关联现在看起来像:
class Booking < ActiveRecord::Base
belongs_to :flight
has_many :passengers
accepts_nested_attributes_for :passengers, reject_if:
lambda {|attributes| attributes['name'].blank?}, :allow_destroy => true
end
class Passenger < ActiveRecord::Base
belongs_to :booking
end
class Flight < ActiveRecord::Base
has_many :bookings
has_many :passengers, through: :bookings
accepts_nested_attributes_for :passengers
accepts_nested_attributes_for :bookings
end
下一步:
我没有使用默认值no_of_passengers
来构建我的嵌套表单,而是使用了cocoon gem,这使得嵌套表单的构建和管理更加容易。我还创建了一个新的params
方法,在其中我允许flight_id
,然后将我的new
方法中的current user
方法作为我的预订实例的参数传递给我new
。所以现在我的def new
@booking = Booking.new(new_booking_params)
@booking.user = current_user if current_user
end
def new_booking_params
params.permit(:flight_id)
end
方法看起来像这样。
params
之后,我必须为create
方法制作另一个bookings
方法,以便在passengers_attributes
表中允许我想要的参数,这包括{{1} }。现在我的create
方法看起来像这样。
def create
@booking = Booking.new(another_booking_params)
respond_to do |format|
if @booking.save
format.html { redirect_to '/booking_confirmed', notice: 'Booking was successfully created.' }
format.json { render :show, status: :created, location: @booking }
else
format.html { render :new }
format.json { render json: @booking.errors, status: :unprocessable_entity }
end
end
end
def another_booking_params
params.require(:booking).permit(:flight_id, :user_id, :no_of_passengers,
passengers_attributes:[:name, :email])
end
最后,我必须将表单调整为这样。
<%= form_for(@booking, url: bookings_path) do |f| %>
<%= f.hidden_field(:flight_id)%>
<%= f.hidden_field(:user_id) %>
<%= f.hidden_field(:no_of_passengers)%>
<%= f.fields_for :passengers do |passenger| %>
<%= render 'passenger_fields', :f => passenger %>
<% end %>
<%= link_to_add_association 'Add Another passenger',f, :passengers, :class => 'btn btn-primary add' %>
<%= submit_tag "Book Now", class: "btn btn-primary book" %>
<% end %>
和passenger_fields
部分看起来像。
<div class="nested-fields form-inline">
<div class="form-group">
<%= f.text_field :name, :class => "form-control", placeholder: "Passenger Name" %>
</div>
<div class="form-group">
<label>-</label>
<%= f.text_field :email, :class => "form-control", placeholder: "Passenger Email" %>
</div>
<div class="links pull-right">
<%= link_to_remove_association "Delete", f, class: "btn btn-danger" %>
</div>
<hr>
</div>
所有这一切都成功了。我希望这会帮助其他人更好地理解嵌套表格