轨与多个条目嵌套形式(Rails nested form with multiple entries

2019-07-18 21:46发布

我不得不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模式:

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

SessionInstructor模型:

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

最后, User模型:

has_many :sezzions
has_many :instructors

我试图创建一个表单Sezzion与嵌套形式SessionInstructor其中有多个选择选项Instructors

我怎样才能做到以下几点:

  1. 嵌套形式SessionInstructor
  2. 使用多重选择选项来获得所有选择Instructorinstructor_id
  3. 隐藏字段在创建/更新通过session_id与每个选择讲师

我有以下的代码截至目前:

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

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


    <%= f.label :instructors %>
    <%= fields_for :session_instructors do |f| %>
      <select multiple>
        <% current_user.instructors.each do |instructor| %>
          <option><%= instructor.name %></option>
        <% end %>
      </select>
    <% end %>

    <%= f.submit %>

<% end %>

非常感谢!

Answer 1:

这就是看似可笑很难在导轨上。

我觉得这样的事情可能工作:

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

这应该创建将设置sezzion [session_instructors_attributes] [instructor_ids]一种形式的元素。

虽然我不知道这实际上是你想要的。 我从来没有尝试过这种使用多选。 如果它不工作,你也可以尝试摆脱的fields_for ,只是使用f.collection_select 。 如果你愿意使用一个复选框,我可以告诉你如何做到这一点是肯定的。

我希望帮助。

编辑:

下面是我通常会用做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%>

有几个“陷阱!” 用这种方法。 当编辑模式,如果你取消选择所有复选框,那么它不会在所有发送的参数。 这就是为什么hidden_field是必要的。 此外,您还需要确保每个表单元素都有一个唯一的id字段。 否则,只有最后一个条目被发送。 这就是为什么我手动设置的值自己。

我复制粘贴,然后进行编辑。 我希望我有足够接近,你可以得到它的工作的语法。

最后编辑:

每低于Sayanee的评论,答案是比我想象的简单一点:

<%= f.collection_select :instructor_ids, current_user.instructors, :id, :name, {}, {:multiple => true} %>


Answer 2:

@Sayanee,你可以发布你的导师如何,sezzions表的样子。 同时做笔记,你不能从讲师对象获取instructor_ids,所以你得到“未定义的方法”的错误。 与您共享当前关联,你可以从Sezzion对象instructor_ids。 所以,你需要通过current_user.sezzions回路current_user.instructors代替。



Answer 3:

这是落实在的has_many的情况下,与HTML multiple_select fields_for嵌套表格的方式:通过关联。 做这样的事情解决了这个问题。 表单视图:

<%= 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不会在生成表单的时候救了你可以不到位your_chosen.id的传递ID(@ sezzion.id)通过形式。 你可以搞定保存在控制器中。

请确保您的控制器初始化变量而产生的形式:您的高清新会是这个样子:

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

在创建功能,第一session_instructor变量通过我们新的功能链接到@sezzion实例变量。 如果你想在创建的传递@每个选择教练sezzion.id的Sezzion实例被保存后在我们的多次选择其它session_instructors必须建立。 。

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


文章来源: Rails nested form with multiple entries