Search code examples
ruby-on-railsruby-on-rails-4nested-attributesupdate-attributes

check new nested attribute added in update action rails 4


i have nested form in which Passenger and passenger_cards are Parent and child respectively

in the form i can add/remove passenger card as i want (took partial support of railscast 197), working nicely .

But when the edit action how do i know that the new card is in added on edit page.

My create action

 @admin_passenger = Passenger.new(admin_passenger_params)
i=0
respond_to do |format|
  if  @admin_passenger.valid?
  params[:passenger][:passenger_cards_attributes].values.each do |p|
    i += 1
    @admin_passenger.card_number = p[:card_number]
    @admin_passenger.card_expiry_month = p[:card_expiry_month]
    @admin_passenger.card_expiry_year = p[:card_expiry_year]
    @admin_passenger.card_cvc = p[:card_cvc]
    if i==1   
      @errors,@error_message = @admin_passenger.create_customer_payment_profile
    else
      @errors,@error_message = @admin_passenger.add_another_card   
    end
    if @errors == true
      flash.now[:alert] = @error_message
      format.html { render :new }
    else
      @admin_passenger.save
      @admin_passenger.get_paymentprofile(@admin_passenger.profile_id)
      passenger_card = @admin_passenger.passenger_cards.build(payment_profile_id: @admin_passenger.payment_profile_id, card_last_4: @admin_passenger.card_last_4, is_active: true, card_exp_month: @admin_passenger.card_expiry_month, card_exp_year: @admin_passenger.card_expiry_year, card_cvc: @admin_passenger.card_cvc)
      passenger_card.save
    end  
      format.html { redirect_to admin_passenger_path(@admin_passenger), notice: 'Passenger was successfully created.' }
      format.json { render :show, status: :created, location: @admin_passenger }
    end
  else
    #flash.now[:alert] = @admin_passenger.check_valid_card_details ?  @admin_passenger.errors.full_messages : @admin_passenger.errors.full_messages << "Invalid Card Details" 
    #@admin_passenger.errors.add(:card_number, "Invalid Card Details")
    format.html { render :new }
    format.json { render json: @admin_passenger.errors, status: :unprocessable_entity }
  end
end

My update Action

respond_to do |format|
  params[:passenger][:action] = params[:passenger][:action].to_i
  if @admin_passenger.update(update_passenger_params)
    logger.warn("=====55===#{@admin_passenger.passenger_cards.inspect }====")
    format.html { redirect_to admin_passenger_path(@admin_passenger), notice: 'Passenger was successfully updated.' }
    format.json { render :show, status: :ok, location: @admin_passenger }
  else
    format.html { render :edit }
    format.json { render json: @admin_passenger.errors, status: :unprocessable_entity }
  end
end

i need to do some process on add card so

def add_card
@admin_passenger = Passenger.find(params[:id])
if params[:passenger].present?
  @admin_passenger.card_number = params[:passenger][:card_number]
  @admin_passenger.card_expiry_year = params[:passenger][:card_expiry_year]
  @admin_passenger.card_expiry_month = params[:passenger][:card_expiry_month]
  @admin_passenger.card_cvc = params[:passenger][:card_cvc]
  puts("===================******")
  logger.warn("passenger==> #{@admin_passenger.card_number.inspect}===year #{@admin_passenger.card_expiry_year.inspect}===month #{@admin_passenger.card_expiry_month.inspect}")
  status = @admin_passenger.check_valid_card_details
  if !status
    flash.now[:alert] = "Invalid Card Details"       
  else
    @errors,@error_message = @admin_passenger.add_another_card
    if @errors == true
      flash.now[:alert] = @error_message
    else          
      redirect_to admin_passenger_path(@admin_passenger), notice: 'Passenger card was successfully added.' 
    end
  end
end

end

my question is if any way to know that a new card is added on edit form so i can call add_card method and further process that card

Thanks


Solution

  • For your nested attributes, You will get Id of previously added passenger cards. Please check your console logs for nested attributes parameter.

    In passenger_cards_attributes =>{"0"=>{"id"=>"105","card_number" => "123"},"1231232444" => {"card_number" => "456"}}.

    Here parameters for card_number "123" was already present, so it will be passed with "id" and for card_number "456" which you have newly created, so that don'y have "id" as in parameter. So, just call "add_card" method for those attributes which do not have ids.