Проблема с именованием / генерацией полей формы в приложении Ruby / Rails - PullRequest
0 голосов
/ 12 декабря 2011

Я немного новичок в Ruby / Rails, который, как мне кажется, включает в себя много "волшебства". Это может быть здорово, но также очень трудно понять, почему что-то работает или (в данном случае) не работает. Моя проблема состоит в том, чтобы выяснить, как назвать / настроить поля формы так, чтобы все «просто работало».

Существует четыре основных объекта, с которыми я работаю: наборы данных, требования, модули и конфигурации (именованные наборы данных, module_requirements, моды и module_configurations ниже). Модули имеют требования (многие ко многим), и может быть несколько наборов данных, которые удовлетворяют определенному требованию (многие к одному). Модуль может иметь много конфигураций (один ко многим). Благодаря этим отношениям мы видим, что Конфигурация может быть связана со многими наборами данных (многие-ко-многим). Фактическая связь между конкретной Конфигурацией и некоторыми конкретными наборами данных управляется через отношение has_and_belongs_to_many.

Я создаю интерфейс, позволяющий пользователям редактировать конфигурацию, выбирая, какие наборы данных будут использоваться для выполнения требований соответствующего модуля.

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

==> The basic data model in more detail:

class Dataset < ActiveRecord::Base
    belongs_to :module_requirement
    has_many :mods, :through => :module_requirement
    has_many :module_configurations, :through => :mods
end

class ModuleRequirement < ActiveRecord::Base
  belongs_to :dataset_type
  has_and_belongs_to_many :mod
  has_many :module_configuration, :through => :mod, :source => :module_configurations
  has_many :dataset
end

class Mod < ActiveRecord::Base
  validates :name,        :presence => true
  validates :description, :presence => true,
                          :length => { :minimum => 5 }

  has_and_belongs_to_many :module_requirements  
  has_many :module_configurations
  has_many :datasets, :through => :module_requirements
end

class ModuleConfiguration < ActiveRecord::Base
  belongs_to :mod
  has_many :module_requirements, :through => :mod
  has_and_belongs_to_many :datasets
end

.

==> From module_configurations_controller.rb:

def edit
    @module_configuration = ModuleConfiguration.find(params[:id])

    # List datasets by their requirements to provide a drop down box for each requirement listing only relevant datasets
    @datasetsByReq = Hash.new

    Dataset.all.collect{ |d| if(!d.module_requirement.nil?)
                               @datasetsByReq[d.module_requirement.id] ||= Array.new   # Create an empty array if needed
                               @datasetsByReq[d.module_requirement.id].push(d)         # Append config to the array
                             end }   

    # Find the selected dataset for each requirement                             
    @selectedDataset = Hash.new
    @module_configuration.datasets.all.collect{ |d| @selectedDataset[d.module_requirement.id] = d}
end


def update
    @module_configuration = ModuleConfiguration.find(params[:id])

    respond_to do |format|
      if @module_configuration.update_attributes(params[:module_configuration])
        format.html { redirect_to @module_configuration, notice: 'Module configuration was successfully updated.' }
        format.json { head :ok }
      else
        format.html { render action: "edit" }
        format.json { render json: @module_configuration.errors, status: :unprocessable_entity }
      end
    end
  end

.

==> From module_configurations/edit.html.erb

<%= simple_form_for(@module_configuration) do |f| %>

  ... other fields here ...

  <!-- Produce one dropdown filled with datasets per requirement: -->
  <% config.mod.module_requirements.each do |req| %>
    <%= f.fields_for :datasets , req do |r|%>

      <% selected = @selectedDataset[req.id].nil? ? -1 : @selectedDataset[req.id].id%>              <== Problem is likely here...

      <%= collection_select :requirement_id, :dataset_id, @datasetsByReq[req.id] || [], :id, :name, <== ...and/or here
                         :include_blank => 'None specified', :selected => selected %> 
    <% end %>
  <% end %>
<% end %>

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

Использование последней версии всего, работающей в Linux.

Спасибо за любую помощь, которую вы можете оказать!


Больше не ищем решения, решенного с помощью другого механизма. Я подтвердил, что проблема связана с тем, как было названо collection_select, но я боюсь, что полное объяснение будет настолько эзотерическим и конкретным, что будет бесполезным для сообщества.

1 Ответ

0 голосов
/ 12 декабря 2011

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

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

accepts_nested_attributes_for :relationship_name

, например, одному классу может понравиться это:

class ModuleConfiguration < ActiveRecord::Base
  belongs_to :mod
  has_many :module_requirements, :through => :mod
  has_and_belongs_to_many :datasets
  accepts_nested_attributes_for :datasets
end

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

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