The button_to is not passing the correct id to the line_item. In the log below you see the bike_id change from the correct '86' to the incorrect '1' (which coincidentally is my user_id). Any help would be appreciated. Below is the error from my development.log, then the code from my view and controllers. Thanks.
development.log
Started POST "/line_items?bike_id=86" for 127.0.0.1 at 2011-08-01 18:09:52 -0400
DEPRECATION WARNING: Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead. (called from <class:ApplicationController> at /Users/willdennis/rails_projects/spinlister/app/controllers/application_controller.rb:8)
Processing by LineItemsController#create as HTML
Parameters: {"authenticity_token"=>"5GYQqvf7U5awhLrZ9Aw910ETf2kqOk3PI315jkjEfMU=", "bike_id"=>"86"}
[1m[35mCart Load (0.6ms)[0m SELECT "carts".* FROM "carts" WHERE ("carts"."id" = 8) LIMIT 1
[1m[36mBike Load (1.2ms)[0m [1mSELECT "bikes".* FROM "bikes" WHERE ("bikes"."id" = 86) ORDER BY bikes.created_at DESC LIMIT 1[0m
[1m[35mSQL (0.5ms)[0m INSERT INTO "line_items" ("bike_id", "cart_id", "created_at", "updated_at") VALUES (1, 8, '2011-08-01 22:09:53.208978', '2011-08-01 22:09:53.208978')
[1m[36mCart Load (1.5ms)[0m [1mSELECT "carts".* FROM "carts" WHERE ("carts"."id" = 8) LIMIT 1[0m
Redirected to http://localhost:3000/carts/8
Completed 302 Found in 251ms
line_items_controller.rb
def create
#cart = current_cart
#bike = Bike.find(params[:bike_id])
#line_item = #cart.line_items.build(:bike_id => #bike)
respond_to do |format|
if #line_item.save
format.html { redirect_to(#line_item.cart,
:notice => 'Line item was successfully created.') }
format.xml { render :xml => #line_item,
:status => :created, :location => #line_item }
else
format.html { render :action => "new" }
format.xml { render :xml => #line_item.errors,
:status => :unprocessable_entity }
end
end
end
views/bikes/show
<%= button_to "Rent this Bicycle!", line_items_path(:bike_id => #bike), {:id => "rentthisbike"} %>
bike.rb
class Bike < ActiveRecord::Base
belongs_to :user
has_many :line_items
attr_accessible :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood, :bike_id
end
line_item.rb
class LineItem < ActiveRecord::Base
belongs_to :bike
belongs_to :cart
accepts_nested_attributes_for :bike, :cart
attr_accessible :bike_id, :bike, :cart, :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood
end
cart.rb
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
belongs_to :user
accepts_nested_attributes_for :line_items
attr_accessible :bike_id, :line_items, :name, :description, :size, :biketype, :price, :photo, :id, :address, :city, :state, :zip, :latitude, :longitude, :neighborhood
end
Can you try this code and post the #### Line item attributes entry from your log file along with the params hash
I think this may be related to your current_cart method but I'm not sure
line_items_controller.rb
def create
#bike = Bike.find(params[:bike_id])
#line_item = current_cart.line_items.build
#line_item.bike = #bike
logger.debug("#### Line item attributes = #{#line_item.inspect}")
respond_to do |format|
if #line_item.save
format.html { redirect_to(#line_item.cart,
:notice => 'Line item was successfully created.') }
format.xml { render :xml => #line_item,
:status => :created, :location => #line_item }
else
format.html { render :action => "new" }
format.xml { render :xml => #line_item.errors,
:status => :unprocessable_entity }
end
end
end
Update.
Your previous code was fine except for this line
#line_item = #cart.line_items.build(:bike_id => #bike)
You were supplying the whole class as the value for the bike ID instead of the id of the bike. I know this is inconsistent with passing form parameters but that's just the way it is.
Related
I'm having a problem creating a nested model with establish_connection using another database.
class Restaurant < ActiveRecord::Base
establish_connection :'f7-api'
has_many :sections, dependent: :destroy
has_many :items, through: :sections
accepts_nested_attributes_for :sections, allow_destroy: true
end
class Section < ActiveRecord::Base
establish_connection :'f7-api'
belongs_to :restaurant
has_many :items, dependent: :destroy
has_many :options, through: :items
accepts_nested_attributes_for :items, allow_destroy: true
end
-
PG::ForeignKeyViolation: ERROR: insert or update on table "sections"
violates foreign key constraint "fk_rails_14e0e2a999" DETAIL: Key
(restaurant_id)=(3) is not present in table "restaurants". : INSERT INTO
"sections" ("title_input_id", "restaurant_id", "created_at",
"updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"
The form parameters from the action are (formatted):
{
"utf8"=>"✓", "authenticity_token"=>"FLe24nnI3fITIS4bpMBDjJ0Ne+F0S3Rh9HgjYIqotR3CpbT/gHa0c3iQi0yUtiCQNdNBYi0ANN75fqiZU6japw==",
"restaurant"=>{
"name"=>"asd", "business_name"=>"", "cnpj"=>"", "description"=>"",
"url"=>"", "phone"=>"", "mobile"=>"", "website"=>"",
"sections_attributes"=>{
"1463797768730"=>{"title"=>"", "_destroy"=>"false"}
}
},
"commit"=>"Save Restaurant"
}
restaurants_controller
# POST /restaurants
# POST /restaurants.json
def create
#restaurant = Restaurant.new(restaurant_params)
respond_to do |format|
if #restaurant.save
format.html { redirect_to #restaurant, notice: 'Restaurant was successfully created.' }
format.json { render :show, status: :created, location: #restaurant }
else
format.html { render :new }
format.json { render json: #restaurant.errors, status: :unprocessable_entity }
end
end
end
def restaurant_params
params.require(:restaurant).permit(
:id,
:name,
:business_name,
:cnpj,
:description,
:phone,
:mobile,
:website,
:user_id,
:street,
:complement,
:number,
:lat,
:lng,
:zip_code,
:neighborhood_id,
:city_id,
:state_id,
:country_id,
photos: [:id, :image, :main],
open_hours: [:id, :weekday, :opens_at, :closes_at],
cuisine_ids: [],
category_ids: [],
sections_attributes: [
:id,
:title,
:restaurant_id,
:_destroy,
items_attributes: [
:id,
:title,
{:description => []},
:section_id,
:price_cents,
:not_equal,
:_destroy,
options_attributes: [
:id,
{:description => []},
:item_id,
:price_cents,
:_destroy
]
]
]
)
end
The solution is to remove foreign_key references in postgres database
I dont know why estabilh_connection is breaking this relationship.
I'm looking to upload multiple images to my 'locations' model. I've called the images model 'assets'. One location has multiple assets. I'm also using paperclip to handle the uploads and nested_form to allow selecting multiple assets.
Weirdly, the locations hash looks to be passing the variables correctly, but they don't appear to be being picked up by the assets model. Any help would be great!
Location model
class Location < ActiveRecord::Base
has_many :location_post
has_many :posts, :through => :location_post
has_many :assets, dependent: :destroy
attr_accessor :asset, :assets_attributes
accepts_nested_attributes_for :assets, :allow_destroy => true
end
Asset model
class Asset < ActiveRecord::Base
belongs_to :location
has_attached_file :asset,
:styles => {
:blurred => "600x300^",:large => "600x600>", :medium => "250x250^" , :thumb => "100x100^"},
#:source_file_options => {:all => '-rotate "-90>"'},
:convert_options => {
:all => '-auto-orient', :blurred => "-blur 0x6 +repage -resize 600x300^"
},
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:bucket => "[bucketname]",
:path => "/:style/:id/:filename"
validates_attachment_content_type :asset, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
Locations Controller
class LocationsController < ApplicationController
...
def new
#location = Location.new
#location.assets.build
#georesult = Geocoder.search(params[:query])
end
def create
#location = Location.find_or_create_by(name: location_params[:name])
respond_to do |format|
if #location.save
format.html { redirect_to #location, notice: ' <borat voice> Great success! </borat voice>' }
format.json { render :show, status: :created, location: #location }
else
format.html { render :new }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /locations/1
# PATCH/PUT /locations/1.json
def update
respond_to do |format|
if #location.update(location_params)
format.html { redirect_to #location, notice: 'Location was successfully updated.' }
format.json { render :show, status: :ok, location: #location }
else
format.html { render :edit }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end
...
private
# Use callbacks to share common setup or constraints between actions.
def location_params
params[:location].permit(:name, :notes, :longitude, :country, :latitude, :query, assets_attributes: [ :asset, :asset_content_type, :asset_file_name, :tempfile, :asset_file_size, :asset_updated_at, :_destroy])
end
end
Form View
<%= nested_form_for(#location, :html=> {:multipart => true}) do |f| %>
...
<%= f.fields_for :assets do |a| %>
<%= a.file_field :asset %>
<%= a.link_to_remove "Remove this image" %>
<% end %>
<%= f.link_to_add "Add an image", :assets %>
...
<%= f.submit "Submit", :class => "btn btn-success submit_location" %>
<% end %>
Log output
Processing by LocationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"n4spoLjq4B3sZSJjqsGFRVjkseOwGgvquAHATBRG1Nk=", "location"=>{"name"=>"York", "notes"=>"", "lat
itude"=>"53.96230079999999", "longitude"=>"-1.0818844", "country"=>"", "assets_attributes"=>{"0"=>{"asset"=>#<ActionDispatch::Http::UploadedFile
:0x007ff739b7bb68 #tempfile=#<Tempfile:/var/folders/sc/gps8hkgj7yg31j81gpnfg9h00000gn/T/RackMultipart20140706-43312-kdpghs>, #original_filename=
"78509.max1024.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"location[assets_attributes][0][asset]\"; filen
ame=\"78509.max1024.jpg\"\r\nContent-Type: image/jpeg\r\n">, "_destroy"=>"false"}}}, "commit"=>"Submit", "id"=>"240"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Location Load (0.4ms) SELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT 1 [["id", 240]]
(0.2ms) BEGIN
(0.3ms) COMMIT
Redirected to http://localhost:3000/locations/240
Completed 302 Found in 9ms (ActiveRecord: 1.6ms)
I see couple of problems in your code:
First thing, you need to remove the following line from Location model:
attr_accessor :asset, :assets_attributes
as its making asset and asset_attributes as virtual attributes which is why they are not saved in database. Also, you don't need asset attribute in Location model as its been taken care by Asset model.
Then, update the location_params as suggested by #Pavan:
def location_params
## Use `require` method
params.require(:location).permit(:name, :notes, :longitude, :country, :latitude, :query, assets_attributes: [ :asset, :asset_content_type, :asset_file_name, :tempfile, :asset_file_size, :asset_updated_at, :_destroy])
end
Next, update the create action as below to ensure Locations are unique by name:
def create
#location = Location.find_by(name: location_params[:name])
unless #location
#location = Location.new(location_params)
end
respond_to do |format|
if #location.save
format.html { redirect_to #location, notice: ' <borat voice> Great success! </borat voice>' }
format.json { render :show, status: :created, location: #location }
else
format.html { render :new }
format.json { render json: #location.errors, status: :unprocessable_entity }
end
end
end
try using <%= a.file_field :asset, :multiple=>"true",:name=>"location[assets][asset][]"%> for handling multiple uploads.
Hope it helps
I have two models, Trips and Locations. A trip has a origin and a destination which are both references to Location:
class Trip < ActiveRecord::Base
attr_accessible :name, :destination, :origin, :start_datetime, :transportation, :trip_type, :destination_attributes, :origin_attributes
enum_attr :trip_type, %w(Hitchhiker Driver)
has_one :origin, :class_name => 'Location' , :primary_key => :origin, :foreign_key => :id
has_one :destination, :class_name => 'Location' , :primary_key => :destination, :foreign_key => :id
accepts_nested_attributes_for :origin, :allow_destroy => true
accepts_nested_attributes_for :destination, :allow_destroy => true
belongs_to :user
validates_presence_of :name, :destination, :origin, :start_datetime, :transportation, :trip_type
end
class Location < ActiveRecord::Base
attr_accessible :address, :latitude, :longitude
geocoded_by :address
before_validation :geocode
validates_presence_of :address
validate :geocoding_was_found
def geocoding_was_found
errors.add(:address, 'is not valid') if latitude.nil? || longitude.nil?
end
end
When calling create in the controller, it saves all of the records (two location records and the trips record) but does not save the association.
def create
#trip = Trip.new(params[:trip])
#trip.user = current_user
respond_to do |format|
if #trip.save
format.html { redirect_to #trip, notice: 'Trip was successfully created.' }
format.json { render json: #trip, status: :created, location: #trip }
else
format.html { render action: "new" }
format.json { render json: #trip.errors, status: :unprocessable_entity }
end
end
end
I am using nested forms so the data for location is being passed in through origin_attributes and destination_attributes. My guess is it is because the two fields are called origin and destination instead of _id.
Hello I am trying to build a multi select to populate a many-to-many join table. I am able to crate the new newform but am getting "AssociationTypeMismatch" when I try to save my record.
The solutions that I am finding on the web are not solving my problem.
Hoping someone can resolve what I should be doing to get rid of "AssociationTypeMismatch"
class Presenter < ActiveRecord::Base
belongs_to :seminar
belongs_to :person
end
class Seminar < ActiveRecord::Base
attr_accessible :description, :title,
has_many :presenters, :foreign_key => "person_id"
has_many :lecturer, :through => :presenters, :source => :person
accepts_nested_attributes_for :lecturer, :presenters
end
class Person < ActiveRecord::Base
attr_accessible :first_name, :last_name
has_many :presentors
has_many :lecturingAt, :through => :presentors
def fullName
first_name + " " + last_name
end
end
seminars_controller.rb
def new
#seminar = Seminar.new
#current_presenters = Person.find(:all)
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #seminar }
end
end
....
def create
#seminar = Seminar.new(params[:seminar])
respond_to do |format|
if #seminar.save
format.html { redirect_to(#seminar, :notice => 'Seminar was successfully created.') }
format.xml { render :xml => #seminar, :status => :created, :location => #seminar }
else
format.html { render :action => "new" }
format.xml { render :xml => #seminar.errors, :status => :unprocessable_entity }
end
end
end
Seminars/_form.html.erb. has which populates my collection select with the names and persion ids of
possible lecurers.
....
<div class="field">
<%= f.label :presenter_id %><br />
<%= collection_select(:seminar,:lecturer,#current_presenters, :id, :fullName,{}, {:multiple=>true} ) %>
....
On submitting the params passed into my controller
Parameters: {...., "seminar"=>{ "lecturer"=>["1", "2"], "title"=>"1234567890", "description"=>"ASDFGHJKL:"}, "commit"=>"Create Seminar"}
Getting error:
ActiveRecord::AssociationTypeMismatch (Instructor(#86075540) expected, got String(#73495120)):.
#seminar = Seminar.new
Try this
#seminar.lecturer_ids = params[:seminar].delete(:lecturer)
#seminar.update_attributes(params[:seminar])
Models:
class User < ActiveRecord::Base
belongs_to :role, :polymorphic => true
class Admin < ActiveRecord::Base
has_one :user, :as => :role
class Dealer < ActiveRecord::Base
has_one :user, :as => :role
class Buyer < ActiveRecord::Base
has_one :user, :as => :role
Dealer controller:
def new
#dealer = Dealer.new
respond_to do |format|
format.html
format.xml { render :xml => #dealer }
end
end
def create
#dealer = Dealer.new(params[:dealer])
respond_to do |format|
if #dealer.save
flash[:notice] = 'Dealer was successfully created.'
format.html { redirect_to [:admin, #dealer] }
format.xml { render :xml => #dealer, :status => :created, :location => #dealer }
else
format.html { render :action => "new" }
format.xml { render :xml => #dealer.errors, :status => :unprocessable_entity }
end
end
end
Error message:
ActiveRecord::AssociationTypeMismatch in Admin/dealersController#create
User(#41048900) expected, got HashWithIndifferentAccess(#23699520)
Request Parameters:
{"authenticity_token"=>"+GkeOOxVi1Fxl7ccbV0Ctt5R6shyMlF+3UWgRow2RdI=",
"dealer"=>{"gender"=>"m",
"forename"=>"",
"surname"=>"",
"company"=>"",
"address1"=>"",
"address2"=>"",
"zipcode"=>"",
"city"=>"",
"country"=>"1",
"user"=>{"email"=>"",
"password"=>""},
"phone"=>"",
"mobile"=>"",
"fax"=>""},
"commit"=>"Submit"}
I guess my problem is that Rails doesn't convert the "user" hash inside the request hash into a User object — but why and how can I make Rails to do that?
Just spent several hours on this including bumping into this thread. Finally found on another forum:
the attribute setter expects to get your params in this form
{ ...,
"user_attributes" => {"email" => "", "password" => ""},
... }
NOT
{ ...,
"user" => {"email" => "", "password" => ""},
... }
In order to get this, your view should look something like this:
form_for #dealer do |f|
...
f.fields_for :user, #dealer.user do |u|
...
end
...
end
This works for me on Rails 3.0.3