0

私の目標は、アイテムが collection_select から選択解除されたときに、保存されたレコードを更新できるようにすることです (その後、そのレコードが再送信されます)。

詳細

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 Pennsylvania Ave NW, Washington, DC 20500" , "350 5th Ave, New York, NY 10118"]}}

4

2 に答える 2

0

別の変形 (gem を使用しない) (もっと難しい方法だと思います! )

まったく削除accept_nested_attributesして、パラメーターを直接操作できます。ただし、この場合、すべてのプロセスを手動で管理する必要があります。レコードを正しく挿入し、レコードを正しく破棄します。

あなたの場合、このようにうまくいくはずです(テストされていません!)。質問に投稿されたパラメーターに基づく例。

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
于 2013-09-21T22:45:01.220 に答える