1

In How to post array values via curl it gives a great example of how to set array values via curl:

$ curl -X POST http://localhost:3000/api/v1/shops.json -d \
  "shop[name]=Supermarket \
  &shop[products][]=fruit \
  &shop[products][]=eggs \
  &auth_token=a1b2c3d4"

What I'm wondering is if there's a way to update an existing array via curl without overwriting the values?

A little more info on what I'm trying to do - I'm trying to create a rails survey app with a HABTM relationship between the users/surveys. After a user takes the survey (in my Android app) it should update the join table with the user/survey so the user isn't served the same survey again. I've been trying to replicate this via curl but have been running into some trouble.

I'm able to update a survey title via this PUT request in curl:

curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X PUT -d '{"title":"123dddTestingPlease rddfsfsfrdf","id":3,"users":[{"id":2,"email":"[email protected]","created_at":"2014-02-28T01:56:09.841Z","updated_at":"2014-02-28T01:56:09.879Z","admin":true,"auth_token":"7acac413cbc22049a3ebf074f45c9847"}]}' http://localhost:3000/surveys/1

But I'm having troubles updating the users array. Ideally it would just append the user I send to the existing user array.

Thanks in advance!

EDIT: First to answer your question - the problem is the user array doesn't seem to be updating at all when I do the curl request. What my end goal is to do is when the user completes the survey on the Android app, I want to send a PUT message to the rails server that will update that survey to contain that user (when the app checks to see if a survey is available, it checks to see if the user has taken the survey).

Here's my survey controller (I stripped everything but Update for readability):

class SurveysController < ApplicationController
  before_action :set_survey, only: [:show, :edit, :update, :destroy]

  # PATCH/PUT /surveys/1
  # PATCH/PUT /surveys/1.json
  def update
    respond_to do |format|
      if @survey.update(survey_params)
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def survey_params
      params.require(:survey).permit(:title, :users)
    end
end

I also tried a variant where I just send the user's auth_token and then I ID the user by that and try to add them to the users list, but that doesn't seem to work either. Here's what that code looked like:

def update
    @survey = Survey.find(params[:id])
    @survey.add_user params[:auth_token]
    redirect_to api_v1_survey_path(@survey)
 end

And the model:

class Survey < ActiveRecord::Base
  has_many :surveytizations
  has_many :questions, :through => :surveytizations
  has_many :users, :through => :completions
  has_many :completions

  def complete_survey (survey, user)
    survey.users << user
    survey.number_taken += 1
    if survey.number_taken == survey.survey_limit
      survey.survey_finished = true
    end
  end

  def add_user auth_token
    user = User.find_user_by_token auth_token
    completions.create(user_id: user.id)
  end

  def find_user(auth_token)
    user = User.find_user_by_token auth_token
    if (user != nil && completions.find_by(user_id: user.id) != nil) 
      return true
    else
      return false
    end
  end

  def self.check_survey (auth_token)
    Survey.all.each do |survey|
      next if survey.survey_finished
      next if survey.find_user auth_token
      return survey.id
    end
  end
end
6
  • Two things: please show your Rails code, and also - what is the problem now? I guess what happened it that arrays is replaced, not updated. If so, the problem is definitely in the controller, so show the code! :) Commented Mar 11, 2014 at 13:48
  • I added my code. The interesting thing is that the curl request above doesn't seem to replace or update the users array. Rather it just skips it. Perhaps because it's actually a join table relationship rather than an actual array within the survey? Commented Mar 11, 2014 at 18:49
  • Ok, sorry for teacher style cat & mouse but I think you'll learn more this way. What do the survey_params return? Is there anything in the log for update action that sounds warning to you? :) Commented Mar 12, 2014 at 9:05
  • So, it appears that you params only accept scalar values. I tried :users => [], users: [] and a few other variants based off a few other SOs but those didn't seem to work. In the development log it seems to just skip the users altogether. I'm obviously missing something :) Commented Mar 12, 2014 at 13:24
  • So in log you should see something like "params not allowed". But to answer I need to know also why you pass whole user object (or at least multiple parameters) and not just ids? Commented Mar 12, 2014 at 13:48

1 Answer 1

1

I ended up figuring it out. here's what I changed my controller to:

 def update 
        @survey = Survey.find(params[:id])
        @user = User.find_user_by_token params[:auth_token]
        @survey.users << @user
        redirect_to api_v1_survey_path(@survey)
      end
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.