Hi I have a table Package that I populate through a form and using the params. This table has a FK to another table Location that holds the lat, lng and address of the package. The Location table uses GeoKit.
My form has fields for the package and a field that allows the user to enter in the name of a location. Google maps helps the user fill in the details with autocomplete and saves the results as json in a hidden field.
I am trying to use strong params as
private
def package_params
params.require(:package).permit( :state, :delivery_date, :length, :height, :width, :weight, destination: [:id, :address, :lat, :lng], origin: [:id, :address, :lat, :lng] )
end
I have also tried
private
def package_params
params.require(:package).permit( :state, :delivery_date, :length, :height, :width, :weight, destination_attributes: [:id, :address, :lat, :lng], origin_attributes: [:id, :address, :lat, :lng] )
end
but origin & destination _attributes are no longer being passed through in the package object of the params.
The package model is
class Package < ActiveRecord::Base
belongs_to :user
has_many :bids, dependent: :destroy
belongs_to :origin, :class_name => 'Location', :foreign_key => 'origin'
belongs_to :destination, :class_name => 'Location', :foreign_key => 'destination'
has_many :locations, autosave: true
accepts_nested_attributes_for :origin, :destination
....
end
the location model is
class Location < ActiveRecord::Base
acts_as_mappable
validates :address, presence: true
validates :lat, presence: true
validates :lng, presence: true
end
The create method is
def create
@package = current_user.packages.build(package_params)
if @package.save
......
end
package.save is failing. This is the error that I am receiving.
ActiveRecord::AssociationTypeMismatch in PackagesController#create Location(#70350522152300) expected, got String(#70350507797560)
I can think of a couple of workarounds but I would like to get this working so I learn from it. I've tried reading the rails api and googling this for a couple of days but I haven't been able to get it too work.
The post data is
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"ZYkfpQBu6fvX7ZmzRw2bjkU+3i6mH0M7JLeqG4b99WI=",
"origin_input"=>"Kimmage, Dublin, Ireland",
"package"=>{
"origin"=>"{
\"address\":\"Kimmage, Dublin, Ireland\",
\"lat\":53.32064159999999,
\"lng\":-6.298185999999987}",
"destination"=>"{
\"address\":\"Lucan, Ireland\",
\"lat\":53.3572085,
\"lng\":-6.449848800000041}",
"length"=>"22",
"width"=>"222",
"height"=>"22",
"weight"=>"0 -> 5",
"delivery_date"=>"2014-10-31"},
"destination_input"=>"Lucan, Ireland",
"commit"=>"Post"}
I know the origin and destination aren't been deserialized, but I don't know why they aren't. Do I have to manually deserialize the string and can I do this in package_params ?
The form that creates this is as follows
<%= form_for(@package, :html => {:class => "form-horizontal", :role => 'form'}) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group">
<input type="text" name="origin_input" placeholder="From" onFocus="geolocate(); autocompleteLocation(this,package_origin)" class="form-control" />
<%= f.hidden_field :origin, class: "form-control" %>
</div>
<div class="form-group">
<input type="text" name="destination_input" placeholder="Destination" onFocus="geolocate(); autocompleteLocation(this,package_destination)" class="form-control" />
<%= f.hidden_field :destination, class: "form-control" %>
</div>
<div class="form-inline form-group">
<div class="input-group col-md-3">
<%= f.text_field :length, placeholder: "L", class: "form-control" %>
<span class="input-group-addon">cm</span>
</div>
<div class="input-group col-md-3">
<%= f.text_field :width, placeholder: "W", class: "form-control" %>
<span class="input-group-addon">cm</span>
</div>
<div class="input-group col-md-3">
<%= f.text_field :height, placeholder: "H", class: "form-control" %>
<span class="input-group-addon">cm</span>
</div>
</div>
<div class="form-group input-group">
<p>Please select the weight range of your package, Weights are in kg</p>
<% options = options_from_collection_for_select(@weights, 'weight', 'weight') %>
<%= f.select :weight, options, class: "form-control dropdown" %>
</div>
<div class="form-group">
<%= f.date_field :delivery_date, class: "form-control" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary", id: "package_post" %>
<% end %>
<%= render 'shared/places_autocomplete' %>