Как сохранить адрес из разных моделей (Страна, Штат, Город, Адрес) в одной форме? - PullRequest
0 голосов
/ 11 октября 2018

Итак, я пытаюсь сохранить в одной форме кучу данных.Часть этих данных - адрес . Этот адрес был разделен на несколько моделей: Страна, Штат, Город и Адрес.

Моя проблема в том, что, честно говоря, я понятия не имею, как управлять этим в контроллере.Я поделюсь тем, что у меня есть на данный момент, и надеюсь, что кто-нибудь может дать мне подсказку.

Должен ли я сделать accepts_nested_attributes_for для всех моделей ?.Как я могу подключить все это наследует поля или внешний ключ для обработки информации?

Модель страны:

class Country < ApplicationRecord
  has_many :states
end

Модель состояния:

class State < ApplicationRecord
  belongs_to :country
  has_many :cities
end

Модель города:

class City < ApplicationRecord
  belongs_to :state
  has_many :addresses

  accepts_nested_attributes_for :addresses
end

Модель адреса:

class Address < ApplicationRecord
  belongs_to :city
  belongs_to :office
end

Модель офиса:

class Office < ApplicationRecord

  has_many :addresses, inverse_of: :office

  accepts_nested_attributes_for :addresses
end

Контроллер офиса Сильные параметры для страны, штата, городаи Адрес (Есть больше параметров, я просто разместил те, которые касаются моей проблемы):

def office_params
      params.require(:office).permit(
     {
        countries_attributes: [
          :id, :name,
          states_attributes: [
            :id, :name,
            cities_attributes: [
            :id, :name,
              addresses_attributes: [
                :id, :street, :state_id
                ]
            ]
          ]
        ]
      },         
)

Новый метод Office:

def new
    @office = Office.new
    @countries = Country.all.map{|c| [ c.name, c.id ] }
    @states = State.all.map{|c| [ c.name, c.id ] }
    #@office.addresses.build.cities.build
    #@office.addresses.counties.states.cities.build
    #@office.addresses.build
  end

Форма офиса: В этой форме я использую fields_for для того, чтобы вложить все поля, вызываемые из соответствующих моделей.Поэтому здесь мне нужно сохранить всю информацию сразу на нескольких моделях.

<%= form_with(model: office, local: true, html: {class: "form-office"}) do |form| %>
        <% if office.errors.any? %>
          <div id="error_explanation">
            <h2><%= pluralize(office.errors.count, "error") %> prohibited this office from being saved:</h2>

            <ul>
            <% office.errors.full_messages.each do |message| %>
              <li><%= message %></li>
            <% end %>
            </ul>
          </div>
        <% end %>

        <div class="row">
          <div class="col-md-6 col-sm-6 col-xs-12">
            <div class="form-group">
              <span><%= form.label :office_name %></span>
              <%= form.text_field :office_name, class: 'form-control' %>
            </div>
          </div>

          <div class="col-md-6 col-sm-6 col-xs-12">
            <div class="form-group">
              <span><%= form.label :office_slug %></span>
              <%= form.text_field :office_slug, class: 'form-control' %>
            </div>
          </div>
        </div>

        <div class="row">
          <div class="col-md-6 col-sm-6 col-xs-12">
            <div class="form-group">
              <span><%= form.label :office_email %></span>
              <%= form.text_field :office_email, class: 'form-control' %>
            </div>
          </div>

          <div class="col-md-6 col-sm-6 col-xs-12">
            <div class="form-group">
              <span><%= form.label :phone %></span>
              <%= form.text_field :phone, class: 'form-control' %>
            </div>
          </div>
        </div>

        <hr>
        <h3 style="color: #B0B0B0;">Office Address</h3>
**Office Address**
        <div class="row">
          <div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-6">
            <%= form.fields_for :countries do |country| %>
              <div class="form-group">
                <span><%= country.label :country %></span>
                <%= select_tag(:country_id, options_for_select(@countries), class: 'form-control', :prompt => "Select Country") %>
              </div>

              <div class="form-group">
                <%= country.fields_for :states do |state| %>
                  <span><%= state.label :state %></span>
                  <%= select_tag(:state_id, options_for_select(@states), class: 'form-control', :prompt => "Select State") %>
              </div>
            </div>
            <div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-6">
                <div class="form-group">
                  <%= state.fields_for :cities do |city| %>
                    <span><%= city.label :city %></span>
                    <%= city.text_field :name, class: 'form-control' %>
                </div>

                  <div class="form-group">
                    <%= city.fields_for :addresses do |address| %>
                      <span><%= address.label :street %></span>
                      <%= address.text_field :street, class: 'form-control' %>
                  </div>

                    <div class="form-group">
                      <span><%= address.label :zip_code %></span>
                      <%= address.text_field :zip_code, class: 'form-control' %>
                    </div>
                    <% end %>
                <% end %>
              <% end %>
            <% end %>
            </div>
        </div>

      <hr>
      <h4 style="color: #B0B0B0;">Comment</h4>

        <div class="row">
          <div class="col-md-12 col-sm-6 col-xs-12 st">
            <div class="comments">
              <%= form.fields_for :comments do |comment_form| %>
                <%= render 'comment_fields', f: comment_form %>
              <% end %>
            </div>
          </div>
        </div>

        <div>
          <div class="col-md-4 offset-md-4">
            <%= form.submit class: 'btn btn-lg' %>
          </div>
        </div>
 <% end %>

1 Ответ

0 голосов
/ 11 октября 2018

Да, вы должны добавить accepts_nested_attributes_for для каждой ассоциации, которую вы хотите обновить через fields_for.

class Country < ApplicationRecord
  has_many :states
  accepts_nested_attributes_for :states
end

class State < ApplicationRecord
  belongs_to :country
  has_many :cities
  accepts_nested_attributes_for :states
end

Однако, если вы сделаете это и правильно определите office_params, сохраните всеВложенные модели возможны при одном вызове Office.create(office_params), не беспокоясь о настройке внешних ключей.То же самое касается обновления, но вы должны будете предоставить скрытые :id поля формы для вложенных моделей, чтобы существующие экземпляры модели можно было найти в БД.

Вам также следует рассмотреть возможность добавления validates_associated к моделям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...