Сложный вопрос Rails с формой на основе существующих ресурсов - PullRequest
4 голосов
/ 19 августа 2011

У вас есть набор связанных моделей, созданных на эшафотах, например, дом , который имеет множество комнат , каждая из которых имеет множество окон , каждая из которых имеетвыбор из замков .
Эти ресурсы уже заполнены данными, т. е. кто-то ввел всю информацию, например: комната под названием «кухня» имеет различные окна, связанные с ней, и у каждого из этих окон пятьразличные блокировки, связанные с ними.

Кто-то приходит и говорит:

Можете ли вы создать форму, которая позволит кому-то создать новый проект, в котором они могут выбрать разные комнаты, окна, а затемуказать замки, которые они хотели бы для этого проекта? (они уже есть в системе, ничего нового добавить, просто ассоциации с новым проектом)

Звучит как вложенная форма, но я потратил много временипытаясь решить эту проблему - есть много уровней вложенности, которые делают это сложно.Есть предложения?

Ответы [ 3 ]

1 голос
/ 22 августа 2011

решение, основанное на сеансах

С такими глубоко вложенными моделями блока выбора на внешнем интерфейсе будет недостаточно ... Предполагая, что вы можете создать current_house, идентификатор которого находится в сеансе (точно так же, какcurrent_user работает).

Как только у вас есть current_house, добавьте различные элементы, перейдя к представлению списка элементов и нажав на ссылку add_to:

  # house_controller.rb
  def add_to
    current_house.polymorphic_items << Kitchen.find(params[:id])
    redirect_to :back
  end

Но есть много подходов к этому решению на основе сеансов, которые сортируютреализует корзину / систему заказов.Возможно, вы захотите добавить current_item, чтобы добавить материал в каждый лист вашего дерева или комнаты вашего дома.

EG после нажатия на кухню, которую вы только что добавили:

before_filter :set_current_item

def add_to
  current_item.windows << Window.find(id)
end

current_item полиморфный: гостиная, ванная и т. Д. Но то, как вы реализуете это, зависит именно от вашей доменной модели...

Как правило, в отношении вложенных форм я следую указаниям рельсов для маршрутов: не углубляйтесь глубже, чем на один уровень, иначе вы окажетесь в беспорядке.

0 голосов
/ 23 августа 2011

Я думаю, что вы можете смоделировать это с одним уровнем вложенных атрибутов, учитывая приведенные ниже модели (на основе ранее существовавших окон / блокировок и комнаты, которой просто нужно смешивать и сопоставлять их в набор окон с заданными блокировками):

class House < ActiveRecord::Base
  has_many :rooms
end

class Room < ActiveRecord::Base
  belongs_to :house
  has_many :window_configs
end

class WindowConfig < ActiveRecord::Base
  belongs_to :room
  belongs_to :window
  belongs_to :lock
end

class Lock < ActiveRecord::Base
  has_many :window_configs
end

class Window < ActiveRecord::Base
  has_many :window_configs
end

... на основе этой настройки модели у вас может быть одна форма дома, в которую вы динамически добавляете определения дочерней «комнаты», для каждого из которых есть имя и коллекция window_configs, в каждом из которых есть два поля выбора (выберите определение окна, а затем определение блокировки). Поскольку вы динамически добавляете несколько комнат с несколькими окнами, вам потребуется JS для заполнения новых элементов формы, но все они могут находиться в одной вложенной форме.

form_for :house do |form|
  # Dynamically add a Room form for each room you want with js
  form.fields_for :room do |room_attributes|
    room_attributes.text_field :name
    # Dynamically add window_config forms on Room w/ JS
    room_attributes.fields_for :window_config do |window_attributes|
      window_attributes.select :window_id, Window.all
      window_attributes.select :lock_id, Lock.all
0 голосов
/ 20 августа 2011

Да, это вложенная форма. Railscasts вложенные формы это отличное место для начала.

Если все уже есть в системе, вы, вероятно, просто хотите установить флажки, чтобы они могли выбирать, что они хотят. Также проверьте метод .build. Если у вас несколько уровней вложенности, вы также можете вручную установить связь, передавая внешний ключ самостоятельно.

...