damax
damax

Reputation: 453

Not all attributes are populated from Backbone model, to Rails backend when doing save

I'm trying to implement simple demo, based on backbone.js and rails4. For this purpose I've created simple model:

app.LocationModel = Backbone.Model.extend({
  defaults : {
    name : "Test name",
    description : "Test description",
  },
});

Later somewhere in the code, I put to the model latitude and longitude taken from Google marker object. Then I call save on the model. In Chrome dev tools I see that Request Payload in POST request contains following information:

{"pos":{"latitude":52.30511992110524,"longitude":16.2103271484375},"name":"Test name","description":"Test description"}

That is correct. On the Rails side I'm trying to receive these JSON object and persist in database in a way:

def create
  @location = Location.new(location_params)
  if @location.save
    render json: @location
  end
end

... where:

def location_params
  puts "test #{params.permit(:name, :description, :pos)}"
  params.permit(:name, :description, :pos)
end

Test put shows: test {"name"=>"Test name", "description"=>"Test description"}

Location db table looks like that:

create_table :locations do |t|
  t.string :name
  t.string :description
  t.float :latitude
  t.float :longitude
  t.timestamps
end

Unfortunately, from unknown for me reason, this "pos" information (latitude & longitude) are not persisted (are nulls). The strange thing happens in server logs, when there are displayed information about parameters taken from request:

Processing by LocationsController#create as JSON   Parameters: {"pos"=>{"latitude"=>52.562995039558004, "longitude"=>16.38336181640625}, "name"=>"Test name", "description"=>"Test description", "location"=>{"name"=>"Test name", "description"=>"Test description"}} Geokit is using the domain: localhost Unpermitted parameters: pos, location test {"name"=>"Test name", "description"=>"Test description"} Unpermitted parameters: pos, location    (0.2ms)  begin transaction   SQL (1.6ms)  INSERT INTO "locations" ("created_at", "description", "name", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", "2014-08-13 09:28:59.092248"], ["description", "Test description"], ["name", "Test name"], ["updated_at", "2014-08-13 09:28:59.092248"]]    (162.1ms)  commit transaction Completed 200 OK in 169ms (Views: 0.8ms | ActiveRecord:
163.8ms)

Why when there are displayed parameters there is an location object => but without "pos" information ? I guess this is also a root cause why there is displayed message about unpermitted "pos" and finally these long & lat are not passed to insert query

Upvotes: 0

Views: 96

Answers (1)

mu is too short
mu is too short

Reputation: 434685

Your Location model has separate latitude and longitude attributes:

create_table :locations do |t|
  #...
  t.float :latitude
  t.float :longitude
  #...
end

rather than a single pos attribute. If you say:

Location.new(:name => '...', :description => '...', :pos => { ... })

then you'll get a Location with only name and description attributes since Location doesn't know anything about pos.

You'll have a better time if everything matches your model all the way down. Your Backbone model should be sending in:

{
  "latitude": 52.30511992110524,
  "longitude": 16.2103271484375,
  "name": "Test name",
  "description":"Test description"
}

and your controller's parameter checking should look like:

def location_params
  params.permit(:name, :description, :latitude, :longitude)
end

Upvotes: 1

Related Questions