2015-10-24 18 views
0

我試圖使用collection_select創建一個HTML多重選擇,以便能夠將具有另一個實體(SubscriptionList)集合的實體(一個Student)更新爲嵌套屬性。這由HABTM ActiveRecord的關係來支持。
我已經通過腳手架創建下列形式的學生:Rails多重選擇放置額外的空白參數

<div class="field"> 
    <%= f.label :first_name %><br> 
    <%= f.text_field :first_name %> 
</div> 
<div class="field"> 
    <%= f.label :last_name %><br> 
    <%= f.text_field :last_name %> 
</div> 
<div class="field"> 
    <%= f.label :file_number %><br> 
    <%= f.text_field :file_number %> 
</div> 
<div class="field"> 
    <%= f.label :subscription_list %><br> 
    <%= f.collection_select(:subscription_lists, SubscriptionList.all, :id, :name, {}, {:multiple => true}) %> 
</div> 

<div class="actions"> 
    <%= f.submit %> 
</div> 

,並繪製多個選擇正確。
不過,如果我填寫表格,並嘗試把實體,我得到這個作爲PARAMS:

{「UTF-8」 =>「✓」,「_method」 =>「補丁」,「authenticity_token 「=」「vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw + mvHAAAbf6ViTQ6tE4lV1Q ==」,「student」=> {「first_name」=>「Mariana」,「last_name」=>「González」,「file_number」=>「12345678」,「subscription_lists」=> 「」,「3」]},「commit」=>「更新學生」,「控制器」=>「學生」,「動作」=>「更新」,「ID」=>「14」}

所以,我的學生是

"first_name"=>" Mariana", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]} 

我覺得它v作爲價值,她很奇怪地會收到["", "3"]。爲什麼我首先收到這個值""

我還張貼在這裏我控制器(行動等即update已爲簡潔起見刪除)

class StudentsController < ApplicationController 
    before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments] 

    # PATCH/PUT /students/1 
    # PATCH/PUT /students/1.json 
    def update 
    puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}" 
    puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}" 
    #puts "\n\n\n\n\n\n\n\n\nWill look for SL with ID: #{params[:subscription_lists_id]}" 
    all_ids = student_params.subscription_lists.collect {|sl| sl.id } 
    @student.subscription_lists = SubscriptionList.find(all_ids) 
    #@student.subscription_lists = SubscriptionList.where(id: all_ids) 
    respond_to do |format| 
     if @student.update(student_params) 
     format.html { redirect_to @student, notice: 'Student was successfully updated.' } 
     format.json { render :show, status: :ok, location: @student } 
     else 
     format.html { render :edit } 
     format.json { render json: @student.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_student 
     @student = Student.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def student_params 
     #params[:student] 
     #params.require(:foo).permit(:bar, {:baz => [:x, :y]}) 
     #params.require(:student).permit(:first_name, :last_name, :file_number, :subscription_lists) 

     params.require(:student).permit! # No strong parameters... 
    end 
end 

其實,我寧願接受StudentSubscriptionList嵌套集合,而不是僅僅receving一個ID數組,但我不確定這是否可能。

任何幫助將非常感激。
問候謹慎

回答

1

關於你的問題已經回答在collection select always adding blank value

當您未選擇任何內容或選擇選項選擇爲默認值時,您將獲得[""]。爲避免這種情況,您必須在收集選擇之前添加hidden_field

​​

hidden_field可以幫助你,當它沒有被選中。如何選擇它?請試試這個。

def update 
    if student_params["subscription_lists"].any? 
     student_params["subscription_lists"].reject!(&:empty?) 
    end 
    respond_to do |format| 
     if @student.update(student_params) 
     format.html { redirect_to @student, notice: 'Student was successfully updated.' } 
     format.json { render :show, status: :ok, location: @student } 
     else 
     format.html { render :edit } 
     format.json { render json: @student.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

我希望這對你有所幫助。

+0

感謝你這樣回答有用。我結束了[本教程](http://shilpi2189.blogspot.com.ar/2013/01/implementing-hasandbelongstomany.html)並最終搞清楚了。由於您的方法看起來正確,我在鼓勵您,但我也發佈了我選擇的解決方案。謝謝! – jmm

+0

沒關係。別客氣。 :) – akbarbin

0

這就是我最終做的事情,主要是在this tutorial之後。

對於控制器:

class StudentsController < ApplicationController 
    before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments] 

    # PATCH/PUT /students/1 
    # PATCH/PUT /students/1.json 
    def update 
    puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}" 
    puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}" 

    @subscription_lists = SubscriptionList.where(:id => params[:subscriptions]) 
    @student.subscription_lists.destroy_all # disassociate the already added 
    @student.subscription_lists << @subscription_lists 

    respond_to do |format| 
     if @student.update(student_params) 
     format.html { redirect_to @student, notice: 'Student was successfully updated.' } 
     format.json { render :show, status: :ok, location: @student } 
     else 
     format.html { render :edit } 
     format.json { render json: @student.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_student 
     @student = Student.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def student_params 
     params.require(:student).permit(:first_name, :last_name, :file_number, subscription_lists: [:id]) 
    end 
end 

而且形式:

<div class="field"> 
    <%= f.label :subscription_list %><br> 
    <%= select_tag "subscriptions", options_from_collection_for_select(SubscriptionList.all, 'id', 'name',@student.subscription_lists.map { |j| j.id }), :multiple => true %> 
    </div> 

希望這是