嵌套表单属性不会保存

时间:2015-11-08 11:07:06

标签: ruby-on-rails ruby

我需要在我正在处理的作业中使用嵌套表单,因为我的嵌套表单属性不会提交给数据库而被卡住了。

这是我的控制器的样子

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检查了乘客桌,但没有返回任何内容。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

在与sunnyk进行配对后,我能够看到错误。

第一个错误是我的class Passengerbelongs_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>

所有这一切都成功了。我希望这会帮助其他人更好地理解嵌套表格