Rails& JQuery:无效的关联。确保使用accepts_nested_attributes_for

时间:2016-03-31 10:56:41

标签: javascript jquery ruby-on-rails ruby ruby-on-rails-4

虽然我想使用link_to_add添加simple_nested_form_for,但会显示以下错误。

ArgumentError (Invalid association. Make sure that accepts_nested_attributes_for is used for :events association.):

stackoverflow中有类似的问题,但它对我不起作用。所以我将此作为一个新问题发布。

我在f.link_to_add中添加_schedule_form.html.erb时出现错误。

_schedule_form.html.erb

<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<br>
<%= f.label :departure_date %>
<div class="input-group date" id="datetimepicker">
  <%= f.text_field :departure_date, class: 'form-control' %>
  <span class="input-group-addon">
    <span class="glyphicon glyphicon-calendar"></span>
  </span>
</div>
<script type="text/javascript">
  $(function () {
    $('#datetimepicker').datetimepicker({format:'MMM-DD-YYYY'});
  });
</script>
<br>
<div id="room">
  <%= f.simple_fields_for :rooms do |a| %>
    <p class="day-number-element-selector"><b>Day&nbsp;<%= a.index.to_i + 1 %></b></p>
    <div id="event">
      <% a.simple_fields_for :events do |e| %>
        <%= e.input :from %>
      <% end %>
    </div>

    #add here!!!

    <%= f.link_to_add "Add event", :events, data: {target: '#event'}, class: "btn btn-primary" %>

    <%= a.input :room %>

  <% end %>
</div>

new_html.erb

<div class="row">
  <div class="col-md-12">
    <p>Create schedule</p>
    <%= simple_nested_form_for(@schedule) do |f| %>
      <%= render 'schedule_form', f: f %>
      <%= f.submit "Create my schedule", class: "btn btn-primary" %>
      <br>
    <% end %>
  </div>
</div>

提供以下型号:

class Schedule < ActiveRecord::Base
  belongs_to :user
  has_many :rooms
  accepts_nested_attributes_for :rooms, allow_destroy: true
  ...

class Room < ActiveRecord::Base
  belongs_to :schedule
  has_many :events
  accepts_nested_attributes_for :events, allow_destroy: true
  ...

class Event < ActiveRecord::Base
  belongs_to :room
  ...

schedule_controller.rb

class SchedulesController < ApplicationController
...
  before_action :set_schedule,  only: %i(show edit update destroy)
...
  def new
    @schedule = Schedule.new
    room = @schedule.rooms.build
    room.events.build
  end

  def create
    @schedule = current_user.schedules.build(schedule_params)
    if @schedule.save
      flash[:success] = "schedule created!"
      redirect_to root_url
    else
      render 'new'
    end
  end

  def edit
    @day_max = Room.where("schedule_id = ?", @schedule.id).maximum(:day)
  end

  def update
    @schedule.rooms.maximum(:day)
    if @schedule.update(schedule_params)
      flash[:success] = "schedule updated!"
      redirect_to root_url
    else
      render 'edit'
    end
  end

  private

    def schedule_params
      params.require(:schedule).permit(:title, :departure_date, rooms_attributes: [:id, :_destroy, :room, :day, events_attributes: [:id, :_destroy, :from, :to, :title, :detail]])
    end

    def set_schedule
      @schedule = Schedule.find(params[:id])
    end

在添加link_to_add之前未显示任何错误。

如果你能给我任何建议,我将不胜感激。

解决!!!

  <div id="room">
    <%= f.simple_fields_for :rooms do |a| %>
      <div id="room_<%= a.object.object_id %>">
        <p class="day-number-element-selector"><b>Day&nbsp;<%= a.index.to_i + 1 %></b></p>

        <%= a.simple_fields_for :events do |e| %>
          <span class="form-inline">
            <%= e.input :from, label: false %>&nbsp;&nbsp;
            <%= e.input :to, label: false%>
          </span>
            <%= e.input :title, label: 'event' %>
        <% end %>
      </div>

      <%= a.link_to_add "Add event", :events, data: {target: "#room_#{a.object.object_id}"}, class: "btn btn-primary" %>

      <%= a.input :room %>

    <% end %>
  </div>

2 个答案:

答案 0 :(得分:1)

div#room应该是这样的:

<div id="room">
  <%= f.simple_fields_for :rooms do |a| %>
    <p class="day-number-element-selector"><b>Day&nbsp;<%= a.index.to_i + 1 %></b></p>

      <% a.simple_fields_for :events do |e| %>
        <div id="event">
         <%= e.input :from %>
        </div>
      <% end %>
    #add here!!!

    <%= a.link_to_add "Add event", :events, data: {target: '#event'}, class: "btn btn-primary" %>

    <%= a.input :room %>

  <% end %>
</div>

答案 1 :(得分:0)

首先放弃了nested_form gem,所以我建议使用现在最新的cocoon

也可能是你过滤的属性

room_attributes: [..., events_attributes: [...]]

由于您的房间属性应为复数形式rooms_attributes

最后一个建议不使用多嵌套。试着看看表单对象模式

希望有所帮助