在 Rails 4 中创建具有多态关系的嵌套形式的新资源

Creating new resources with nested form with polymorphic relationships in Rails 4 presence

我似乎无法从具有多态关联的嵌套表单成功创建新资源。

问题似乎出在多态 'belongs_to' 关系的验证上。例如:

class DealerUser < User
  belongs_to :dealer, polymorphic: true, foreign_key: :loginable_id, foreign_type: :loginable_type
  validates :dealer, presence: true
end

我正在尝试创建一个名为 Dealer 的新资源。

class Dealer < ActiveRecord::Base
  has_many :dealer_locations, dependent: :destroy
  has_one :dealer_user, as: :loginable, dependent: :destroy

  accepts_nested_attributes_for :dealer_locations, allow_destroy: true
  accepts_nested_attributes_for  :dealer_user, allow_destroy: true

  validates :name, presence: true, length: { maximum: 255 }, uniqueness: { case_sensitive: false }
  validates_associated :dealer_locations
end

我的表单代码:

<%= form_for(@dealer) do |d| %>
    <%= render 'shared/error_messages', object: d.object %>
  <br>
    <div class="form-group">
      <%= d.label :name %>
      <%= d.text_field :name, class:"form-input-field" %>
    </div>

      <h4>Login Credentials</h4><br>
      <%= d.fields_for :dealer_user do |du| %>

          <div class="form-group">
            <%= du.label :email %>
            <%= du.text_field :email, class:"form-input-field" %>
          </div>
          <div class="form-group">
            <%= du.label :password %>
            <%= du.password_field :password, class:"form-input-field" %>
          </div>
      <% end %>
    <%= d.submit class: "btn btn-large btn-primary" %>
<% end %>

控制器:

class DealersController < ApplicationController
  def new
    @dealer = Dealer.new
    @dealer.build_dealer_user
  end

  def create
    @dealer = Dealer.new(dealer_params)

    puts @dealer.inspect
    puts @dealer.dealer_user.inspect

    if @dealer.save
       redirect_to(@dealer, :notice => 'Dealer was successfully created.')
    end

  def dealer_params
    params.require(:dealer).permit(:name, dealer_user_attributes: [:email, :password, :id])
  end
end

当我提交表单时,出现 DealerUser.dealer can't be blank 错误。

#<Dealer id: nil, name: "NAME", created_at: nil, updated_at: nil>
#<DealerUser id: nil, type: "DealerUser", email: "fake@email.com", loginable_id: nil, loginable_type: "Dealer",...

看起来关联有效,因为您可以看到类型字段已设置。

2016 年 3 月 11 日更新:参数

{"utf8"=>"✓", "authenticity_token"=>"...", 
"dealer"=>{"name"=>"ZZ WATER", 
"dealer_user_attributes"=>{"email"=>"...", "password"=>"[FILTERED]"}, 
"dealer_locations_attributes"=>{"0"=>{"phone"=>"...", "contact_email"=>"...", 
"address_attributes"=>{"line_1"=>"line1", "line_2"=>"", "city"=>"city", "country_code"=>"US", "state_code"=>"CA", "zip_code"=>"00000"}}}}, "commit"=>"Create Dealer"}

这是操作顺序问题吗? DealerUser 需要一个 ID 才能通过验证,但 Dealer ID 在保存到数据库之前不会被设置,这不会发生,因为它没有通过验证。谁能给我一些指导。

此外,这是我正在做的工作的简化版本,也有嵌套的位置和地址。我在 rails 上使用 ruby 也只有几个月的时间。谢谢。

我创建了一个新的类似项目。我也遇到了同样的错误。在我尝试解决这个问题时,我偶然发现了 inverse_of,现在它起作用了。

现在试试

class DealerUser < User
  # ..
  belongs_to :dealer, polymorphic: true, foreign_key: :loginable_id, foreign_type: :loginable_type, inverse_of: :dealer_user
  # ..
end

class Dealer < ActiveRecord::Base
  # ..
  has_one :dealer_user, as: :loginable, dependent: :destroy, inverse_of: :dealer
  # ..
end