Rails嵌套表单属性未在编辑时显示

时间:2015-11-27 10:25:35

标签: ruby-on-rails ruby-on-rails-4 nested-forms

我正在开发一个拥有多个分支机构的代理商,代理机构和分支机构都可以拥有地址。我为他们创建了模型,如下所示:

# agency.rb
has_many :branches
has_one :address
accepts_nested_attributes_for :branches, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :address, reject_if: :all_blank, allow_destroy: true


# branch.rb 
belongs_to :agency
has_one :address
accepts_nested_attributes_for :address, reject_if: :all_blank

# address.rb
belongs_to :agency
belongs_to :branch

我有一个代理机构表单,应该允许我创建/编辑代理商及其地址,以及添加/编辑/删除分支机构及其地址。

以下是代理机构表格:

<%= form_for(@agency) do |f| %>
  <div class="box-body">

    # errors and messages etc etc ...

    <div class="field">
      <%= f.label :name %><br>
      <%= f.text_field :name, class: 'form-control' %>
    </div>

    # more agency fields

    <%= f.fields_for :address do |address| %>
      <%= render 'addresses/address_fields', f: address %>
    <% end %>

    #other fields which all work fine

    <div id="branches">
      <%= f.fields_for :branches do |branch| %>
        <%= render 'branch_fields', f: branch %>
      <% end %>
      <div class="links">
        <%= link_to_add_association 'add branch', f, :branches %>
      </div>
    </div>
    </div>

  <%= f.submit 'Save Changes', class: 'btn btn-primary' %>

<% end %>

以下是分支字段(部分表格):

  # branch name ...
  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>

  # I will explain this bit below
  <% if f.object.new_record? %> 
    <% f.object.build_address %>
  <% end %>
  ###

  <%= f.fields_for :address do |address| %>
    <%= render 'addresses/address_fields', f: address %>
  <% end %>

  # other branch fields that work fine

  <%= link_to_remove_association "remove branch", f %>

以下是代理商控制人员:

class AgenciesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_agency, only: [:show, :edit, :update]
  # before_action :build_address, only: [:new, :edit]

  def index
    @agencies = Agency.all
  end

  def show
  end

  def create
    @agency = Agency.new(agency_params)

    respond_to do |format|
      if @agency.save
        format.html { redirect_to @agency, notice: 'Agency was successfully created.' }
        format.json { render :show, status: :created, location: @agency }
      else
        format.html { render :new }
        format.json { render json: @agency.errors, status: :unprocessable_entity }
      end
    end
  end

  def new
    @agency = Agency.new
    @agency.build_address
    @agency.build_domain_name
    @agency.branches.build
    @agency.services.build

    # @agency.branches.build_addresses
    # @agency.branches.each do |branch|
    #   branch.build_address
    # end
  end

  def edit
  end

  def update
    respond_to do |format|
      if @agency.update(agency_params)
        format.html { redirect_to @agency, notice: 'Agency was successfully updated.' }
        format.json { render :show, status: :ok, location: @agency }
      else
        format.html { render :edit }
        format.json { render json: @agency.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_agency
      @agency = Agency.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def agency_params
      params.require(:agency).permit(:name, :logo, :description, :phone_number, :alt_phone_number, :email, :alt_email,
                                                          services_attributes:
                                                            [:id, :name, :description, :_destroy],
                                                          address_attributes:
                                                            [:id, :first_line, :second_line, :third_line, :city_town, :post_code, :_destroy],
                                                          domain_name_attributes:
                                                            [:id, :domain],
                                                          branches_attributes:
                                                            [:id, :name, :description, :phone_number, :alt_phone_number, :_destroy, :email, :alt_email,
                                                              services_attributes:
                                                              [:id, :name, :description, :_destroy],
                                                            address_attributes:
                                                              [:id, :first_line, :second_line, :third_line, :city_town, :post_code, :_destroy]
                                                            ]
                                                          )
    end
end

为漫长的代码道歉。 我最初面临的问题是,当我添加新分支时,地址字段没有显示出来。经过一番挖掘后,我在SO上发现了一个问题:有人建议运行f.object.build_address 就在调用分支的字段之前。这适用于在代理表单上创建新分支,但在保存并返回编辑代理页面后,分支的地址字段为空白。但是,地址已正确保存到数据库。我认为这是因为build_address行在编辑时会覆盖内容,这就是为什么我试图将它包装在if循环中但是我几乎可以肯定这是错误的。

如何在控制器中正确构建嵌套分支地址属性,以便在添加新代理和/或分支时正确显示字段?当我稍后回来编辑代理商和分支机构时,如何确保正确显示保存的值。

我已经做了很多阅读和挖掘,我无法看到任何正常的问题,如使用错误的标签(&lt;%= /&lt;%)无济于事。任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:0)

尝试这些修改:

<%= f.fields_for @agency.address do |address| %>
  <%= render 'addresses/address_fields', f: address %>
<% end %>

#other fields which all work fine

<div id="branches">
  <%= f.fields_for @agency.branches do |branch| %>
    <%= render 'branch_fields', f: branch %>
  <% end %>