0

私は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持つネストされたフォームを使用してフォームを作成しようとしています。SessionInstructorInstructors

どうすれば次のことができますか:

  1. のネストされたフォームSessionInstructor
  2. 複数選択オプションを使用して、選択したすべての を取得しInstructorますinstructor_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 %>

どうもありがとう!

4

3 に答える 3

4

これは、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][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} %>
于 2013-01-29T19:00:28.420 に答える
0

これは、has_many :through 関連付けの場合に、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 は次のようになります。

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.id を各選択インストラクターと共に渡したい場合、Sezion インスタンスが保存された後に構築する必要があります。.

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
于 2015-12-29T08:20:18.543 に答える