具有嵌套资源的表单:无法保持关联

时间:2014-09-23 22:22:04

标签: ruby-on-rails

我的嵌套资源表单有问题。数据模型很简单:

class Event < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: [:slugged, :finders]
  has_many :event_contents
end

class EventContent < ActiveRecord::Base
  belongs_to :event
end

我的表格:

= simple_form_for([:admin, @event, @event.event_contents.new], remote: true) do |f|
  .chat-form
    .input-cont
      = f.input :content, label: false, input_html: { class: 'form-control' }    
    .btn-cont
      %span.arrow
      = f.submit 'invia', class: 'btn blue icn-only'

控制器:

class Admin::EventContentsController < AdminController
  def create
    @event_content = EventContent.new event_content_params
    @event_content.user_id = current_user.id if current_user
    if @event_content.save
      respond_to do |format|
        format.js { render :nothing => true }
      end
    else

    end
  end

  private
  def event_content_params
    params.require(:event_content).permit(
      :content,
      :event_id,
      :user_id
      )
  end
end

当我在params而不是event_id中提交帖子时,我有事件“slug”

pry(#<Admin::EventContentsController>)> params
=> {"utf8"=>"✓", "event_content"=>{"content"=>"uhm"}, "commit"=>"invia", "action"=>"create", "controller"=>"admin/event_contents", "event_id"=>"test-test-test"}

记录是在db中创建的,但event_id为nil,因此关联被破坏。 为什么而不是event_id我有事件slug ???

更新

问题是控制器:

def create
    @event = Event.find params[:event_id]
    @event_content = @event.event_contents.build event_content_params
    @event_content.user_id = current_user.id if current_user
    if @event_content.save
      respond_to do |format|
        format.js
      end
    else

    end
  end

1 个答案:

答案 0 :(得分:0)

也许尝试执行以下操作:

    在您的活动模型中
  1. 添加accepts_nested_attributes_for :event_contents
  2. 在收集:event_contents replace

    时,在表单中
  3. f.input :content, label: false, input_html: { class: 'form-control' }
    

    以下内容:

    f.fields_for :event_contents do |content|
    content.input :content
    end
    
  4. 更新 Events 控制器中的强大参数,以包含{:event_contents_attributes},这可能看起来像下面的内容,具体取决于您需要通过的其他参数:

    params.require(:event).permit(:name, {:event_contents_attributes => [:content]})
    
  5. 在您的事件控制器中,更新def new以包含此订单项event_content = @event.event_contents.build

  6. 所有这一切,我相信您会希望将其路由到您的事件控制器而不是您的EventContents控制器,因为:event_contents嵌套在:event中。看起来您的表单目前正在提交给EventContents控制器。另外,我不认为你的simple_form_for @event.event_contents.new中的这个论点是必要的。

    这是我根据你的问题构建的。它不是管理员命名空间,但可能会有帮助。

    class EventsController < ApplicationController
    
    
     def new
        @event = Event.new
        event_content = @event.event_contents.build
      end
    
    def create
        @event = Event.new(event_params)
        respond_to do |format|
            if @event.save
                format.html { redirect_to @event, notice: 'Event was successfully created.' }
                format.json { render :show, status: :created, location: @event }
                format.js
            else
                format.html { render :new }
                format.json { render json: @event.errors, status: :unprocessable_entity }
            end
        end
    private
     def event_params
          params.require(:event).permit(:name, {:event_contents_attributes => [:content]})
        end
    end
    

    活动模式:

    class Event < ActiveRecord::Base
        has_many :event_contents
        accepts_nested_attributes_for :event_contents
    end
    

    最后是表格:

    <%= form_for(@event) do |event| %>
    
      <div class="field">
        <%= event.label :name %><br>
        <%= event.text_field :name %>
      </div>
    
        <%= event.fields_for :event_contents do |content| %>
            <div class="field">
            <%= content.label :content %>
            <%= content.text_field :content %>
        </div>
        <% end %>
    
      <div class="actions">
        <%= event.submit %>
      </div>
    <% end %>