簡體   English   中英

在Rails中,如何使用accepts_nested_attributes_for創建嵌套對象?

[英]In Rails, how do I create nested objects using accepts_nested_attributes_for?

在我的Rails應用程序中,我試圖為TrainingClass模型設置創建表單。 我希望此表單允許用戶在同一表單內創建多個ClassMeeting模型(與TrainingClass模型具有屬植物關系),並且我正在使用accepts_nested_attributes_for做到這一點。 不幸的是,每當我提交表單時,我都會收到錯誤消息: Meetings class can't be blank

我意識到這是因為ClassMeeting具有validates :class_id, presence: true ,並且因為TrainingClass在保存之前無法擁有ID,但是我不確定解決此問題的正確方法。 (我可以想到幾種可能的方法,但它們並不是精確的解決方案。)有什么想法嗎? 謝謝您能給我的任何幫助。

注意:我知道過去已經問過很多類似的問題。 但是,這些問題大多數都是過時的,並且答案已經過時,而且都沒有解決我的問題。


這是我的代碼。 請記住,盡管為簡潔起見,我簡化了某些方面,但ClassMeetingTrainingClass模型之間的關系保持不變:

ClassMeeting模型:

# == Schema Information
#
# Table name: class_meetings
#
#  id         :integer         not null, primary key
#  class_id   :integer
#  start      :datetime
#  end        :datetime
#  location   :string(255)
#  created_at :datetime        not null
#  updated_at :datetime        not null
#

class ClassMeeting < ActiveRecord::Base
  attr_accessible :start, :end, :location

  validates :class_id, presence: true
  validates :start, presence: true
  validates :end, presence: true
  validates :location, presence: true, length: {maximum: 255}

  belongs_to :training_class, foreign_key: :class_id, inverse_of: :meetings
end

TrainingClass模型:

# == Schema Information
#
# Table name: training_classes
#
#  id            :integer         not null, primary key
#  description   :string(255)
#  created_at    :datetime        not null
#  updated_at    :datetime        not null
#

class TrainingClass < ActiveRecord::Base
  attr_accessible :description, :meetings_attributes

  validates :description, length: {maximum: 255}

  has_many :meetings, class_name: :ClassMeeting, foreign_key: :class_id, inverse_of: :training_class

  accepts_nested_attributes_for :meetings, allow_destroy: true
end

TrainingClasses控制器:

class TrainingClassesController < ApplicationController
  def new
    @training_class = TrainingClass.new()
    @training_class.meetings.build
  end

  def create
    @training_class = TrainingClass.new()

    if @training_class.update_attributes(params[:training_class])
        redirect_to @training_class, notice: 'Class was successfully created.'
    else
        render "new"
    end
  end
end

TrainingClass表格(查看):

<%= form_for @training_class do |f| %>
    <%= render 'shared/error_messages', object: f.object %>

    <%= f.text_area :description %>

    <h2>Schedule</h2>
    <%= f.fields_for :meetings do |meeting| %>
        <%= meeting.label :start, "Start of Meeting:" %>
        <%= meeting.text_field :start %>

        <%= meeting.label :end, "End of Meeting:" %>
        <%= meeting.text_field :end %>

        <%= meeting.label :location, "Location:" %>
        <%= meeting.text_field :location %>
    <% end %>

    <%= f.submit class:"btn btn-large btn-primary" %>
<% end %>

好的,我找到了解決問題的方法。 我需要做的就是驗證ClassMeeting模型中training_class的存在,而不是class_id的存在。 這樣,仍然可以驗證訓練類的存在,但是驗證器不會干擾accepts_nested_attributes_for的模型保存方法:

class ClassMeeting < ActiveRecord::Base
  attr_accessible :start, :end, :location

  validates :training_class, presence: true # :training_class instead of :class_id
  validates :start, presence: true
  validates :end, presence: true
  validates :location, presence: true, length: {maximum: 255}

  belongs_to :training_class, foreign_key: :class_id, inverse_of: :meetings
end

我仔細研究了這個示例,嘗試了與代碼的差異,但最終,我的問題通過使用:inverse_of得以解決。

有關子關聯驗證失敗的信息,請參見accepts_nested_attributes_

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM