在Rails 4中使用具有多态关系的嵌套表单创建新资源

时间:2016-03-09 21:14:42

标签: ruby-on-rails forms nested-forms polymorphic-associations

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

似乎问题在于多态性的归属' 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",...

看起来关联正在起作用,因为您可以看到类型字段已设置。

更新3/11/16:params

{"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才能通过验证,但是经销商ID在被保存到数据库之前不会被设置,因为它没有通过验证,所以不会发生这种情况。有人可以给我一些指导。

此外,这是我正在处理的简化版本,也有嵌套的位置和地址。我在轨道上使用红宝石也只有几个月的时间。谢谢。

1 个答案:

答案 0 :(得分:2)

我创建了一个新的类似项目。我也得到了同样的错误。在我试图解决这个问题的过程中,我偶然发现了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