2013-09-21 55 views
0

我的目標是能夠在從一個collection_select中取消選擇項目時更新已保存的記錄(然後重新提交該記錄。)在此先感謝您的幫助!如何在Rails中刪除使用collection_select保存的記錄?

詳細

我已經有了一個Newsavedmaps一種形式。 Newsavedmaps可以有很多路標。用戶可以在collection_select中選擇航點,並且當他們保存Newsavedmap時,這些航點將保存到他們自己的數據庫表中。

問題:當用戶打開他們保存的Newsavedmap時,我希望他們能夠取消選擇一個航點。當他們再次保存Newsavedmap時,我想要刪除選定的航點。

這是我維護的Rails 2.3X應用程序,這就是爲什麼collection_select使用下面的不同格式。

型號

class Newsavedmap < ActiveRecord::Base 
    belongs_to :itinerary 
    has_many :waypoints, :dependent => :destroy 
    accepts_nested_attributes_for :waypoints, :reject_if => lambda { |a| a[:waypointaddress].blank? }, :allow_destroy => true 
end 

查看

<% form_for @newsavedmap, :html => { :id => 'createaMap' } do |f| %> 
     <%= f.error_messages %>    
     <%= f.text_field :name, {:id=>"savemap_name", :size=>30 }%></p> 

     <%= collection_select :waypoints, :waypointaddress, @newsavedmap.waypoints, :waypointaddress, :waypointaddress, {}, { :multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints" } %> 

    <% end %> 

Newsavedmaps控制器

def create 
    @newsavedmap = Newsavedmap.new(params[:newsavedmap]) 
    waypoint = @newsavedmap.waypoints.build 

    respond_to do |format| 
    if @newsavedmap.save 
     flash[:notice] = 'The new map was successfully created.' 
     format.html { redirect_to "MYURL"} 
     format.xml { render :xml => @newsavedmap, :status => :created, :location => @newsavedmap } 
    else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @newsavedmap.errors, :status => :unprocessable_entity } 
    end 
    end 
end 


def update 
    @newsavedmap = Newsavedmap.find(params[:id]) 

    if @newsavedmap.itinerary.user_id == current_user.id 
    respond_to do |format| 
     if @newsavedmap.update_attributes(params[:newsavedmap]) 
     flash[:notice] = 'Newsavedmap was successfully updated.' 
     format.html { redirect_to "MYURL" } 
     format.xml { head :ok } 
     else 
     format.html { render :action => "edit" } 
     format.xml { render :xml => @newsavedmap.errors, :status => :unprocessable_entity } 
     end 
    end 
    else 
    redirect_to '/' 
    end 
end 

創建新記錄時的參數

參數:{「newsavedmap」=> {「name」=>「我的地圖名稱」,其他字段不在上面,「waypoints」=> {「waypointaddress」=> 「1600賓夕法尼亞大道西北,華盛頓特區20500」,「350 5th Ave,紐約,紐約10118」]}}

+0

你能發佈它們來自你的表單 – gotva

+0

添加PARAMS。事實證明,上面的內容是在航點數據庫中創建一個新的空記錄(而不是每個航點都有一個地址的兩個航點記錄)。我認爲這是因爲我的控制器正在告訴窗體在每次有新航點時建立一個航點Newsavedmap,但它完全忽略了數據。有任何想法嗎? – KDP

+0

關於DB中的空記錄:你是對的。在'create'方法中,你從params初始化一個新的'@ newsavedmap',然後建立一個新的'waypoints'並保存@newsavedmap - 這保存@newsavedmap和建立的航點。刪除此建築物的方法創建 – gotva

回答

0

我認爲你的問題是正確建立的形式(和它來自它的參數)。

我建議

  1. 看看寶石cocoonnested_form
  2. 添加waypoints_attributes到attr_accessible
  3. 在窗體

和Rails實現傭工從寶石(從點#1)魔術應該做其他工作

+0

途徑感謝您的迴應,gotva。不幸的是,我不能依靠寶石。但是我確實有一個問題:無論如何,我是否需要包含attr_accessible,如果是,它會發生什麼?關於寶石的 – KDP

+0

:我認爲在沒有寶石的情況下爲'accept_nested_attributes'正確構建表單會很困難。關於'attr_accessible':不需要,但在這種情況下,您應該關心手動分配參數,像這樣@ newsavedmap.waypoints_attributes = params [:newsavedmap] [:waypoints_attributes]。如果你想添加'attr_accessible'將它添加到'Newsavedmap'模型中(並且記住如果沒有設置attr_accessible,那麼默認情況下所有屬性都在這個列表中) – gotva

+0

Thanks,Gotva!我將跳過attr_accessible。我讀過你的評論,但必須有一種方法來添加和刪除collection_select的記錄,而不使用嵌套表單的gem,對吧?有任何想法嗎? – KDP

0

另一個變種(不使用寶石)(我覺得難多了!

你可以刪除accept_nested_attributes,並直接使用你的params。但在這種情況下,您應該手動管理所有進程:正確插入記錄,正確銷燬它們。

在你的情況下,它應該像這樣(沒有測試!)。該示例基於您在問題中發佈的參數。

def create 
    # delete params 'waypoints' it will be manage manually 
    waypoints = params[:newsavedmap].delete(:waypoints) 
    @newsavedmap = Newsavedmap.new(params[:newsavedmap]) 
    waypoints.each do |waypoint| 
    @newsavedmap.waypoints.build(:waypointaddress => waypoint) 
    end 
    if @newsavedmap.save 
    ... 
    end 
end 

主要的麻煩將在方法update

def update 
    # delete params 'waypoints' it will be manage manually 
    waypoints = params[:newsavedmap].delete(:waypoints) 

    # find and setup attributes 
    @newsavedmap = Newsavedmap.find(params[:id]) 
    @newsavedmap.attributes = params[:newsavedmap] 

    # TROUBLES start here 
    # destroy not checked (but existed in DB) waypoints 
    existed_waypoints = @newsavedmap.waypoints 
    existed_waypoint_addresses = existed_waypoints.map(&:waypointaddress) 
    new_waypoints = [] 
    waypoints.each do |waypoint| 
    if existed_waypoint_addresses.include?(waypoint) 
     # existed waypoint was selected on the form 
     # find it and add to new_waypoints 
     new_waypoints << @newsavedmap.waypoints.find_by_waypointaddress(waypoint) 
    else 
     # new waypoint was selected on the form 
     # build it and add to new_waypoints 
     new_waypoints << @newsavedmap.waypoints.build(:waypointaddress => waypoint) 
    end 
    end 
    # setup new records for waypoints 
    @newsavedmap.waypoints = new_waypoints 

    if @newsavedmap.save 
    # destroy existed but not selected waypoints 
    (existed_waypoints - new_waypoints).map(&:destroy) 
    ... 
    end 
end 
+0

Gotva,我非常感謝這次更新。不過,我想在這裏使用嵌套表單而不是試圖繞過它們。有一種方法可以用collection_select添加和刪除記錄,對吧? – KDP

相關問題