Rails вложенная форма с несколькими записями

У меня есть модель Sezzion :

attr_accessible  :description
has_many :session_instructors, :dependent => :destroy
has_many :instructors, :through => :session_instructors
accepts_nested_attributes_for :session_instructors
accepts_nested_attributes_for :instructors

Instructor model:

attr_accessible :bio
has_many :sezzions, :through => :session_instructors
has_many :session_instructors, :dependent => :destroy

SessionInstructor model:

attr_accessible :instructor_id, :sezzion_id
belongs_to :sezzion
belongs_to :instructor

Наконец, модель User :

has_many :sezzions
has_many :instructors

Я пытаюсь создать форму для Sezzion с вложенной формой для SessionInstructor , которая имеет несколько опций выбора для Instructors .

Как я могу сделать следующее:

  1. nested form for SessionInstructor
  2. use multiple select option to get all the selected Instructor's instructor_id
  3. hidden field to pass in the created/updated session_id with each select instructor

На данный момент у меня есть следующий код:

<%= form_for(@sezzion) do |f| %>

    <%= f.label :description %>
    <%= f.text_area :description %>


    <%= f.label :instructors %>
    <%= fields_for :session_instructors do |f| %>
      
    <% end %>

    <%= f.submit %>

<% end %>

Спасибо огромное!

0
nl ja de

3 ответы

Это то, что кажется невероятно трудным в Rails.

Я думаю, что что-то вроде этого может работать:

<%= f.fields_for :session_instructors do |si| %>
  <%= si.collection_select :instructor_ids, current_user.instructors, :id, :name, multiple: true>
<% end %>

Это должно создать элемент формы, который установит sezzion [session_instructors_attributes] [instructionor_ids].

Хотя я не уверен, действительно ли это то, что вы хотите. Я никогда не пробовал это, используя multi select. Если он не работает, вы также можете попытаться избавиться от fields_for и просто использовать f.collection_select . Если вы хотите использовать флажок, я могу показать вам, как это сделать точно.

Надеюсь, это поможет.

<�Сильный> Edit:

Вот как я обычно делал это с помощью check_box :

<%= f.fields_for :session_instructors do |si| %>
  <%= si.hidden_field "instructor_ids[]" %>
  <% current_user.instructors.each do |i| %>
    <%= si.check_box "instructor_ids[]", i.id, i.sezzions.include?(@sezzion), id: "instructor_ids_#{i.id}" %>
    <%= label_tag "instructor_ids_#{i.id}", i.name %>
  <% end %>
<% end%>

Есть пара «gotchas!» с помощью этого метода. При редактировании модели, если вы отмените выбор всех флажков, он не отправит параметр вообще. Вот почему необходим hidden_field . Кроме того, вам нужно убедиться, что каждый элемент формы имеет уникальное поле id . В противном случае отправляется только последняя запись. Вот почему я вручную задал значение самостоятельно.

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

ЗАВЕРШЕНИЕ:

По словам Саяни, ответ был немного проще, чем я думал:

<%= f.collection_select :instructor_ids, current_user.instructors, :id, :name, {}, {:multiple => true} %>
3
добавлено
Спасибо @Geoff! Он почти работает с <% = f.collection_select: instructionor_ids, current_user.instructors,: id,: name, multiple: true%> , поскольку он создает одну запись в SessionInstructor . Также я добавил attr_accessible: instructionor_ids , чтобы предотвратить ошибки массового присвоения. Но он не создает несколько записей ... Я думаю, что хотел бы изучить один с флажками ... как бы вы это сделали? Еще раз спасибо!
добавлено автор Sayanee, источник
Извините за поздний ответ @Geoff! Большое вам спасибо за вашу помощь еще раз! К сожалению, до сих пор не получилось работать. Я пытаюсь установить флажок и undefined method instructionor_ids [] возникает ошибка в строке <% = si.hidden_field "instructionor_ids []"%> . Удаление скрытой строки поля полностью дает метод undefined merge для ошибки 3: Fixnum для строки
добавлено автор Sayanee, источник
Я, наконец, получил его, чтобы работать с несколькими выборами! Большое спасибо за ваши подсказки и помощь :) это <% = f.collection_select: instructionor_ids, current_user.instructors,: id,: name, {}, {: multiple => true}%> ,
добавлено автор Sayanee, источник
Сохранение только первого звучит так, будто он не может распознать массив. Попытка использования "instructionor_ids []" вместо : instructionor_ids . Я также обновляю свой ответ с помощью маршрута checbox , который я использовал ранее.
добавлено автор Geoff, источник

@Sayanee, можете ли вы опубликовать, как выглядят ваши инструкторы, таблица секций. Также обратите внимание: вы не можете получить инструкторские объекты из объекта Instructor, поэтому вы получаете ошибку «неопределенного метода». С существующей ассоциацией, которую вы поделили, вы можете получить инструктор_ид из объекта Sezzion. Таким образом, вам нужно выполнить цикл через current_user.sezzions вместо current_user.instructors.

0
добавлено

Это способ реализации fields_for вложенной формы с html multiple_select в случае has_many: через объединение. Решила это, сделав что-то вроде этого. Вид формы:

<%= form_for(@sezzion) do |f| %>
...

    <%= fields_for :session_instructors do |g| %>
        <%= g.label :instructor, "Instructees List (Ctrl+Click to select multiple)" %>:
        <%= g.select(:instructor_id, Instructor.all.collect { |m| [m.name, m.id] }, {}, { :multiple => true, :size => 5 }) %>
        <%= g.hidden_field :your_chosen_variable_id, value: your_chosen.id %>
    <% end %>
...
<%= f.submit %>

<% end %>

Примечание. Поскольку @sezzion не будет сохранен во время создания формы, вы не сможете передать этот id (@ sezzion.id) вместо your_chosen.id через форму. Вы можете справиться с этим сбережением в контроллере.

Убедитесь, что ваш контроллер инициализирует переменные при создании формы: ваш def new может выглядеть примерно так:

def new
  @sezzion = Sezzion.new
  @sezzion.session_instructor.build
  @sezzion.instructors.build
end

Теперь контроллер создания должен иметь возможность принимать сильные параметры, необходимые для множественного выбора, поэтому метод sezzion_params может выглядеть примерно так:

def sezzion_params
    params.require(:sezzion).permit(:description, :any_other_fields,
                                 :session_instructors_attributes  => 
                                     [:instructor_id => [], :your_chosen_id => Integer])
end

В функции create первая переменная session_instructor связана с переменной экземпляра @sezzion через нашу новую функцию. Другие session_instructors в нашем множественном выборе должны быть созданы после того, как экземпляр Sezzion будет сохранен, если вы хотите передать в созданном @ sezzion.id с каждым инструктором по выбору. ,

def create
    @sezzion = Sezzion.new(sezzion_params)
    @startcount=1 #The first element of the array passed back from the form with multiple select is blank
    @sezzion.session_instructors.each do |m|
      m.instructor_id = sezzion_params["session_instructors_attributes"]["0"]["instructor_id"][@startcount]
      m.your_chosen_variable_id = your_chosen.id
      @startcount +=1
    end

    if @sezzion.save
        sezzion_params["session_instructors_attributes"]["0"]["instructor_id"].drop(@startcount).each do |m|
        @sezzion.session_instructors.build(:instructor_id => sezzion_params["session_instructors_attributes"]["0"]["instructor_id"][@startcount],
                                 :your_chosen_variable_id => your_chosen.id).save
        @startcount += 1
      end
      flash[:success] = "Sezzion created!"
      redirect_to root_url
    else
      flash[:danger] = "There were errors in your submission"
      redirect_to new_sezzion_path
    end
end
0
добавлено
pro.ruby
pro.ruby
1 181 участник(ов)

Язык программирования Ruby Additional docs: https://rubyreferences.github.io/rubyref/ Invite: https://telegram.me/joinchat/Be4rsT2NuB3CyJaF26j1kA Кто хочет компилировать: @crystal_ru (его синтаксис основан на Ruby) Участник @proDOT

Ruby, Rails, Hanami | dry-rb
Ruby, Rails, Hanami | dry-rb
1 180 участник(ов)

https://telegram.me/rubyjob - Ruby Job По вопросам - @eugene_shved

Ruby School .us
Ruby School .us
1 045 участник(ов)

Чат-болталка для учеников руби-школы и не только. Правила: https://telegra.ph/Pravila-chata-Rubi-shkoly-03-13

Random Ruby Chat
Random Ruby Chat
589 участник(ов)

Правила публикации вакансий: https://t.me/codenamecrud/60865

Rubyata
Rubyata
333 участник(ов)

Коммюнити Ruby и Ruby On Rails Флуд не приветствуются. Вакансии можно публиковать только и ТОЛЬКО по пятницам с хештегом #вакансия.

Ruby Talks
Ruby Talks
236 участник(ов)

Национальная Флеймотека

RubyRush
RubyRush
189 участник(ов)

rubyrush.ru программирование для самых новичков

Rails Chat
Rails Chat
87 участник(ов)

You are welcome to discuss Ruby On Rails development process and other stuff