Rails 4,更新嵌套的多态资源

时间:2021-05-10 02:42:02

I have set up polymorphic resource using accepts_nested_attributes_for but for some reason whenever I try to update, instead of just updating the current record, it just create a new one instead. Can anyone tell me what the problem is? Thanks.

我已经使用accepts_nested_attributes_for设置了多态资源,但出于某种原因,每当我尝试更新时,而不是仅仅更新当前记录,它只是创建一个新的。谁能告诉我这是什么问题?谢谢。

vendors_controller.rb

class VendorsController < ApplicationController
  before_action :authenticate_user! #check if user logged in
  before_action :set_vendor, only: [:show, :edit, :update, :destroy]

  def index
    @vendors = current_company.vendors
  end

  def new
    @vendor = current_company.vendors.build
    @vendor.addresses.build
  end

  def create
    @vendor = current_company.vendors.build(vendor_params)
    if @vendor.save
      flash[:notice] = 'New Vendor Added'
      redirect_to vendors_url
    else
      flash[:error] = 'Could not save vendor information. Please try again.'
      render 'new'
    end
  end

  def show
  end

  def edit
    #@vendor = Vendor.find(params[:id])
    #@vendor.addresses.find_or_initialize_by(addressable_id: @vendor.id, addressable_type: 'Vendor')
  end

  def update
    #@vendor = Vendor.find(params[:id])
    if @vendor.update(vendor_params)
      flash[:notice] = 'Vendor Updated'
      redirect_to vendors_path
    else
      flash[:error] = 'Could not save vendor information. Please try again.'
      render 'edit'
    end
  end

  def destroy
    #Vendor.find(params[:id]).destroy
    @vendor.destroy
    flash[:notice] = "Asset deleted"
    redirect_to vendors_url
  end

  private

  def vendor_params
params.require(:vendor).permit(:name, :vendorID, :contact, :email, :phone, :image, :remove_image, addresses_attributes: [:street_1, :street_2, :city, :state, :zip] )
  end

  def set_vendor
    @vendor = Vendor.find(params[:id])
  end

  def current_company
    current_user.company
  end
end

_form.html.erb

<div class="row">
  <div class="col-md-4 col-md-offset-4">
    <div class="card card-block" style="background-color:#f5f5f5">

  <%= form_for @vendor do |f| %>

         <div class="form-group">
        <%= f.label :name, 'Vendor Name' %><br />
        <%= f.text_field :name, autofocus: true, required: true, class:'form-control' %>
      </div>

      <div class="form-group">
        <%= f.label :vendorID, 'Vendor ID/Number' %><br />
        <%= f.text_field :vendorID, class:'form-control' %>
      </div>

      <div class="form-group">
        <%= f.label :contact, 'Main Contact Person' %><br />
        <%= f.text_field :contact, class:'form-control' %>
      </div>

      <div class="form-group">
        <%= f.label :email %><br />
        <%= f.email_field :email, class:'form-control' %>
      </div>

      <div class="form-group">
        <%= f.label :phone %><br />
        <%= f.phone_field :phone, class:'form-control' %>
      </div>

      <%= f.fields_for :addresses do |a| %>
          <div class="form-group">
            <%= a.label :street_1, 'Street' %><br />
            <%= a.text_field :street_1, class:'form-control' %>
          </div>

          <div class="form-group">
            <%= a.label :street_2, 'Street 2 (Optional)' %><br />
            <%= a.text_field :street_2, class:'form-control' %>
          </div>

          <div class="form-group">
            <%= a.label :city, 'City' %><br />
            <%= a.text_field :city, class:'form-control' %>
          </div>

          <div class="form-group">
            <%= a.label :state, 'State' %><br />
            <%= a.text_field :state, class:'form-control' %>
          </div>

          <div class="form-group">
            <%= a.label :zip, 'Zip Code' %><br />
            <%= a.text_field :zip, class:'form-control' %>
          </div>
      <% end %>

      <div class="actions form-group"><br>
        <%= f.submit 'Save Vendor', class: 'btn btn-primary' %>
        <%= link_to 'Cancel', :back, class: 'btn btn-default' %>
      </div>

  <% end %>
</div>

vendor.rb

class Vendor < ActiveRecord::Base
  belongs_to :company
  has_many :asset

  has_many :addresses, as: :addressable, dependent: :destroy
  accepts_nested_attributes_for :addresses, reject_if: RejectDeeplyNested.blank?
end

address.rb

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

2 个解决方案

#1


0  

you need to change your permitted parameters like this

你需要像这样改变你允许的参数

params.require(:vendor).permit(:name, :vendorID, :contact, :email, :phone, :image, :remove_image, addresses_attributes: [:street_1, :street_2, :city, :state, :zip, :id] )

#2


-1  

You need to add optional: true to your relationship:

您需要为您的关系添加可选:true:

class Address < ApplicationRecord
  belongs_to :addressable, polymorphic: true, optional: true
end

Forgot to mention, that optional is available only on Rails > 5

忘了提一下,那个可选项仅在Rails> 5上可用

#1


0  

you need to change your permitted parameters like this

你需要像这样改变你允许的参数

params.require(:vendor).permit(:name, :vendorID, :contact, :email, :phone, :image, :remove_image, addresses_attributes: [:street_1, :street_2, :city, :state, :zip, :id] )

#2


-1  

You need to add optional: true to your relationship:

您需要为您的关系添加可选:true:

class Address < ApplicationRecord
  belongs_to :addressable, polymorphic: true, optional: true
end

Forgot to mention, that optional is available only on Rails > 5

忘了提一下,那个可选项仅在Rails> 5上可用