0

I have followed this Rails 4 Unpermitted Parameters for Array but it doesn't work for me. Here's my model

class Building
  include Mongoid::Document
  include Mongoid::Spacial::Document

  field :address,            :type => String
  field :location,           :type => Array, spacial: {lng: :longitude, lat: :latitude, return_array: true }
end

in controller

def update
  ret = building_params.has_key?(:address) ? building_address_path(@building) : edit_building_path(@building)
  respond_to do |format|
    if @building.update(building_params)
      format.html { redirect_to ret, notice: 'Building was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: 'edit' }
      format.json { render json: @building.errors, status: :unprocessable_entity }
    end
  end
end

def building_params
  params.require(:building).permit(:address, :location => [])
end

html form

<input id="building_location" name="building[location]" type="text" value="[112.70665740967, -7.26961135864]" />

server log

Started PATCH "/id/buildings/52fb014862696b06ad100000" for 192.168.12.211 at 2014-02-13 14:08:24 +0700
Processing by BuildingsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"j/n8Sv1CmEf5LKQMjNb7iQndJjDzWqkxsGrVIdS6i54=", "building"=>{"location"=>"[112.75631079999994,-7.272195699999999]", "address"=>"Jalan Dharmawangsa"}, "commit"=>"Simpan", "locale"=>"id", "id"=>"52fb014862696b06ad100000"}
  MOPED: 127.0.0.1:27017 COMMAND      database=admin command={:ismaster=>1} runtime: 6.4688ms
  MOPED: 127.0.0.1:27017 QUERY        database=development collection=buildings selector={"_id"=>BSON::ObjectId('52fb014862696b06ad100000')} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 8.3167ms
  MOPED: 127.0.0.1:27017 QUERY        database=development collection=users selector={"$query"=>{"_id"=>BSON::ObjectId('52fb013b62696b06ad000000')}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil runtime: 9.1527ms
Unpermitted parameters: location
default_url_options is passed options: {}

Unpermitted parameters: location
Redirected to http://bikinibottom:3000/id/buildings/52fb014862696b06ad100000/address
Completed 302 Found in 1280ms

EDIT:

I add this to Model

def location=( loc )
  location = eval(loc)
end

there's no error at all but the location isn't saved

Community
  • 1
  • 1
spondbob
  • 1,523
  • 2
  • 17
  • 34

3 Answers3

0

Looking at params passed to your controller, it seems that "location" attribute passed as string instead of arrays,
Parameters: {"utf8"=>"✓", "authenticity_token"=>"j/n8Sv1CmEf5LKQMjNb7iQndJjDzWqkxsGrVIdS6i54=", "building"=>{"location"=>"[112.75631079999994,-7.272195699999999]", "address"=>"Jalan Dharmawangsa"}, "commit"=>"Simpan", "locale"=>"id", "id"=>"52fb014862696b06ad100000"}

For verifying the fact that parameter 'building[location]' contains string data, print the class of params[:building][:location] and it should print the String

If parameters is passed as string(as seen in above parameters passing), then change the code as below code:

def building_params
  params.require(:building).permit(:address, :location)
 end
Sanjiv
  • 813
  • 6
  • 13
  • now I got error page `Mongoid::Errors::InvalidValue in BuildingsController#update`. I think I have to parse the string as array as defined in Model, but I don't know how – spondbob Feb 13 '14 at 07:31
0

My suggesting would be that you should send the parameter as array as shown in below code:

<input id="building_location" name="building[location]" type="text" value=[112.70665740967, -7.26961135864] />

and reconvert back building params code back to

def building_params
  params.require(:building).permit(:address, :location => [])
end

Or if you can not do that, they you have to parse the params 'building[location]' like as shown in below code

def building_params
  params[:building][:location] = params[:building][:location][1..-2].split(',') unless params[:building][:location].blank?
  params.require(:building).permit(:address, :location => [])
end
Sanjiv
  • 813
  • 6
  • 13
  • I still got "Unpermitted parameters: location" from your second code, but not twice like in my question, remain the last one – spondbob Feb 13 '14 at 07:58
  • what about my edited question, if u have any suggestions – spondbob Feb 13 '14 at 07:59
  • Does save even calling your code "location=" ? Can you print your logs or put some statement inside the that function? Regarding the earlier question, I have updated my previous answer. – Sanjiv Feb 13 '14 at 08:12
  • yes it's called, I put "puts 'hello'" and it's printed in console. How can I have such array value in text field? currently I just write `= f.text_field :location` – spondbob Feb 13 '14 at 08:58
  • your new answer still produce Unpermitted parameters: location like before – spondbob Feb 13 '14 at 09:18
  • How location field value get assign ? Using some jquery plugin or some select box? – Sanjiv Feb 13 '14 at 12:10
  • yes javascript, I've checked it's well assigned. I've found the solution, I posted it in my question above, stackoverflow didn't allow me to post answer because of my reputation :( – spondbob Feb 13 '14 at 12:28
0

[OP's solution pasted below as an answer]

I've found the answer here. As you see in my server log, there are two Unpermitted parameters: location because I called building_params twice in update action (line 2 and 4).

As soon as I changed line 2 to ret = params[:building].has_key?(:address) ... and apply @sanjiv 's solution, there's still problem.

The input value is "[112.75631079999994,-7.272195699999999]" in string, based on @sanjiv 's solution that will be :

params[:building][:location][0] = "[112.75631079999994"
params[:building][:location][1] = "-7.272195699999999]"

note the parentheses. Then I fixed it by:

def building_params
  params[:building][:location] = eval(params[:building][:location])
  params.require(:building).permit(:address, :location => [])
end

eval() gives you conversion to array from string with parentheses. But why I can't do this one?

# controller
def building_params
  params.require(:building).permit(:address, :location)
end

# model
def location=( loc )
  location = eval(loc)
end

does rails already know in controller if :location is array? there's no error message in server log

jam
  • 3,640
  • 5
  • 34
  • 50