Cannot insert row into table through create action - ruby-on-rails

I'm sure there has to be a very simple solution to my problem but i don't know why i cant seem to put my finger on it, the problem is that I'm trying to submit a form but every time i submit the form the create action controller gives the following error
Mysql2::Error: Column 'preffered_players' cannot be null: INSERT INTO saved_sessions (preffered_players, session_id, preffered_opponents, game_id, game_type, opponents_list, banned_players, players_list) VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
how ever all these values that the error says are null are passed through parameters as soon as the form is submitted, can anyone tell me how to use the parameter values that i get from the form to fill in the little nulls in my query, create controller is as follow
def create
opponents_list = params[:opponents_list]
banned_players = params[:banned_players]
game_type = params[:game_type]
session_id = params[:session_id]
preffered_opponents = params[:preffered_opponents]
game_id = params[:game_id]
players_list = params[:players_list]
preffered_players = params[:preffered_players]
#saved_sessions = SavedSession.new(params[:saved_sessions])
respond_to do |format|
if #saved_sessions.save
format.html { redirect_to(#game, :notice => 'Game was successfully created.') }
format.xml { render :xml => #game, :status => :created, :location => #game }
else
format.html { render :action => "new" }
format.xml { render :xml => #game.errors, :status => :unprocessable_entity }
end
end
end
thanks for any advice...
i'm including the form code however its very messy(its a huge form) plus its in haml :)
- form_tag('/saved_sessions',:method => :post, :id => "new_game") do
.select_option
.list_col1
.fl
%img{:alt => "image", :border => "0", :src => "/images/happy_face.png"}/
.blue_col
= text_field_tag :preffered_opponents, "", :class => :blue_bar
.clr
.list_col2
.list_col2_top_row
.radio_row
.fl
%input{:type => "radio", :name => "battle_scale", :value => "3"}
.fl 3 vs 3
.fl
%input{:type => "radio", :name => "battle_scale", :value => "5"}
.fl 5 vs 5
.clr
%div
.fl
%img{:alt => "image", :border => "0", :src => "/images/sad_face.png"}/
.fl
/%input#banned_players.white_bar{:type => "text"}/
= text_field_tag :banned_players, "", :class => :white_bar
.clr
.versus_row
#inputs-vs.versus_col1
.versus_col_row
.blue_col
/%input#input-1-vs.blue_bar{:type => "text"}/
= text_field_tag 'input-1-vs', "", :class => :blue_bar
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.clr
.versus_col_row
.blue_col
/%input#input-2-vs.blue_bar{:type => "text"}/
= text_field_tag 'input-2-vs', "", :class => :blue_bar
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.clr
.versus_col_row
.blue_col
/%input#input-3-vs.blue_bar{:type => "text"}/
= text_field_tag 'input-3-vs', "", :class => :blue_bar
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.clr
.versus_col_row
.blue_col
/%input#input-4-vs.blue_bar{:type => "text"}/
= text_field_tag 'input-4-vs', "", :class => :blue_bar
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.clr
.versus_col_row
.blue_col
/%input#input-5-vs.blue_bar{:type => "text"}/
= text_field_tag 'input-5-vs', "", :class => :blue_bar
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.clr
.versus_col2
%img{:alt => "0", :border => "0", :src => "/images/vs.png"}/
#inputs.versus_col1
.versus_col_row
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.blue_col
/%input#input-1.pink_bar{:name => "blah", :type => "text"}/
= text_field_tag 'input-1', "", :class => :pink_bar
.clr
.versus_col_row
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.blue_col
/%input#input-2.pink_bar{:name => "blah", :type => "text"}/
= text_field_tag 'input-2', "", :class => :pink_bar
.clr
.versus_col_row
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.blue_col
/%input#input-3.pink_bar{:name => "blah", :type => "text"}/
= text_field_tag 'input-3', "", :class => :pink_bar
.clr
.versus_col_row
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.blue_col
/%input#input-4.pink_bar{:name => "blah", :type => "text"}/
= text_field_tag 'input-4', "", :class => :pink_bar
.clr
.versus_col_row
.fl
%img{:alt => "image", :border => "0", :src => "/images/lock.png"}/
.blue_col
/%input#input-5.pink_bar{:name => "blah", :type => "text"}/
= text_field_tag 'input-5', "", :class => :pink_bar
.clr
.clr
.session_row
%p
%b You can save and share this session by entering your email. A unique code will be sent
%p.small_text (Session are stored for 30 days)
.seesion_send_row
.fl
/%input.big_white_bar{:type => "text"}/
= text_field_tag 'email_bar', "", :class => :big_white_bar
.fl
%span 2+2=
%span
%span
/%input.small_bar{:type => "text"}/
= text_field_tag 'code_bar', "", :class => :small_bar
.fl
/%a{:href => "#."}
/%img{:alt => "image", :border => "0", :src => "/images/send_button.png"}/
= submit_tag("Send")
hope this can help you guys better understand the problem..

You seem to be pulling from 2 different places. The block of code at the top of the method is pulling the values from the top level of the incoming params, but then later you initialize a new SavedSession using the params[:saved_sessions] input. The two things don't seem to match...
if saved_sessions.opponents_list is found at opponents_list = params[:opponents_list] in the first line, then when you later try to save params[:saved_sessions], you're getting it from a different spot in the params...
EDIT: so you do not need both of the sets of values you have in the action. if you build your form like this (or at least something like this) you'll get the params correctly and can just blindly send them into SavedSession.new, and then call .save.
- form_for(#aved_session) do |f|
-.blue_col
= f.text_field :preffered_opponents, "", :class => :blue_bar
If you allow f.text_field to build the id and name then rails magic will make sure that they are named/id'd correctly and then more rails magic interprets them and builds your input parameters correctly. This will build your params as:
params = {:saved_session => {:preferred_opponents => "text value" }...
Then you can pull those params out:
saved_session_input = params[:saved_session]
and pass them into new just like you are. the difference is that now those parameters are actually IN there.
The way you have it is like this:
params = {:preferred_opponents => "text value", :saved_session => {:preferred_opponents => nil }...
this means you're passing nil in for the expected values for new. Note that you don't actually assign your local values to the new saved_session before calling save.
I hope this is clearer.

Related

API POST with array using HTTP gem (or RestClient)

I'm having trouble with this api and can't seem to get over the hump. Using the HTTP gem (though I'm flexible and can use RestClient if that gets me an answer quicker!). Anyway, I'm having trouble posting an array. everything else is good, I just can't figure out this "itemsarray" in the printaura api found here in the addorder method: PrintAura API
I'm running this:
def self.submitorder
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:itemsarray => {:item => [
:product_id => 423,
:brand_id => 33,
:color_id => 498,
:size_id => 4,
:front_print => 1389517,
:front_mockup => 1390615,
:quantity => 1
]}
})
puts JSON.parse(req)
end
And my output is this:
{"status"=>false, "error_code"=>19, "result"=>19, "message"=>"You cannot place an order without items, Please fill the items array with all the required information. Full API documentation can be found at https:/www.printaura.com/api/"}
Gosh, if someone could look at that and help me out I would forever appreciate it.
def self.submitorder
itemsarray = { :items => [ { :product_id => 423, :brand_id => 33, :color_id => 498, :size_id => 4, :quantity => 1, :front_print => 1389517,
:front_mockup => 1390617 } ] }
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:items => Base64.encode64(itemsarray.to_json)}
)
puts JSON.parse(req)
I really hopes this helps somebody some years from now haha
To create a array in JSON you use an array in Ruby. Its that easy.
require 'json'
def self.submitorder
req = HTTP.post("https://api.printaura.com/api.php", :json => {
:key => APIKEY,
:hash => APIHASH,
:method => "addorder",
:businessname => "this is a secret too",
:businesscontact => "thats a secret",
:email => "my#email.com",
:your_order_id => "1",
:returnlabel => "FakeAddress",
:clientname => "ShippingName",
:address1 => "ShippingAddressLine1",
:address2 => "ShippingAddressLine2",
:city => "ShippingCity",
:state => "ShippingState",
:zip => "ShippingZip",
:country => "US",
:customerphone => "dontcallme",
:shipping_id => "1",
:items => [
{
:product_id => 423,
:brand_id => 33,
:color_id => 498,
:size_id => 4,
:front_print => 1389517,
:front_mockup => 1390615,
:quantity => 1
}
]
})
puts JSON.parse(req)
The API lists a items parameter which should contain an array of objects. It says nothing about itemsarray.

Load a hash on grouped_collection_select rails form

currently, I have a hash like this:
#lg = {
"Latin East Group" => [
{:id => 2, :name => "HONGKONG"},
{:id => 3, :name => "NINGBO, ZHEJIANG"},
{:id => 4, :name => "SINGAPORE"},
{:id => 5, :name => "LARCHMONT, NY"},
{:id => 6, :name => "CHICAGO, IL"},
{:id => 7, :name => "HAIPHONG"},
{:id => 8, :name => "DANANG"},
{:id => 9, :name => "HANOI"},
{:id => 10, :name => "MARSEILLE"},
{:id => 11, :name => "LONDON"},
{:id => 12, :name => "EDINBURGH"},
{:id => 13, :name => "AMSTERDAM"},
{:id => 14, :name => "HOCHIMINH"},
{:id => 15, :name => "SHANGHAI"}
],
"Latin West Group" => [],
"Others" => [
{:id => 16, :name => "Brazil" },
{:id => 17, :name => "Mexico" },
{:id => 18, :name => "Columbia"}
]
}
Now, I am using select2 with my form, and I wanna create a dropdown menu from that hash instance variable. I want the keys of the hash will be the optgroups, and the option values are gonna be the name sin the hash like Singapore, Brazil... Therefore, I am wondering what is the correct syntax for it. Currently, this is my code:
_form_body.haml:
%div.col-md-8
= f.grouped_collection_select :origin_locations, #lg, #lg.keys, #lg.values, {:selected => f.options[:origin_locations]}, {class: 'form-control select2-multiple origin_locations', :multiple => true}
pricing_histories_controller.rb:
def load_location_groups
#lg = {}
location_groups = LocationGroup.all.includes(:locations).each { |group|
#lg[group.name]= group.locations.map{|l| {id: l.id,name: l.name}}
}
# location_groups.each_with_index do |location_group, index|
arr = Location.where("id NOT IN (SELECT DISTINCT(location_id) FROM location_group_assignments)").pluck(:id,:name)
#location_groups = {}
#lg["Others"] = arr.map{ |e| {id: e.first, name: e.last}}
end
I will get the error:
ActionView::Template::Error (["Latin East Group", "Latin West Group",
"Others"] is not a symbol nor a string)
So, I am wondering what I am doing wrong here. Any suggestions would be appreciated. Thanks and have a nice day.

How to set and get the default value in date_select rails

So i have a edit form which has year start and end date. I want to show db stored values as default dates.
I have tried this
<%= f.input :year_start_date, :label => 'Year Start Date', :as => :date_select, :include_blank => false,
:input_html => { :id => 'y_start_date'}, prompt: { day: year_start_date.day, month: Date::MONTHNAMES[year_start_date.month], year: year_start_date.year}, data: year_start_date %>
So its fine and started to show db stored values.
But the issue is when am changing only month, parameters will be
"year_start_date(1i)" => "", "year_start_date(2i)" => "3", "year_start_date(3i)" => ""
and in the controller am doing
[ school_params['year_start_date(1i)'], school_params['year_start_date(2i)'], school_params['year_start_date(3i)'] ].join('-').to_date
since it contains empty strings it throws invalid date error.
I want the default values( in this case date and year) when nothing is selected. How to achieve this?
Edit 1:
params
{
"utf8" => "✓",
"_method" => "patch",
"authenticity_token" => "abcffdgfdgfgfgf==",
"school" => {
"name" => "Test School",
"board_id" => "1",
"board_registration_number" => "",
"subdomain" => "testschool",
"email" => "",
"website" => "",
"address" => "NA",
"city" => "NA",
"pincode" => "",
"country_id" => "1",
"country_state" => "Tamil Nadu",
"phone" => "NA",
"inc_year" => "",
"handler_id" => "14451",
"year_start_date(1i)" => "",
"year_start_date(2i)" => "1",
"year_start_date(3i)" => "",
"year_end_date(1i)" => "",
"year_end_date(2i)" => "",
"year_end_date(3i)" => ""
},
"button" => "",
"controller" => "sat/schools",
"action" => "update",
"id" => "2"
}
Instead of using that ugly date/datetime input you can simply use the date picker provided by the browser without having to add additional libraries:
f.input :year_start_date, :label => 'Year Start Date', as: :string, input_html: { type: "date" }

Rails form submitting without some params

my form is submitting without params in "Customer Information" and "Shipping Information". The form is rendered in a modal and looks like this
#formShipping.modal.fade{"aria-hidden" => "true", "aria-labelledby" => "productShippingLabel", :role => "dialog", :tabindex => "-1"}
.modal-dialog
.modal-content
.modal-header
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only Close
%h4#myModalLabel.modal-title Payment Form
.modal-body
/ Button trigger modal
.hide-info
.panel.panel-default
.panel-heading Customer Information
.panel-body
.col-md-3
.col-md-6
%label{:for => "email"} Email Address
%input.form-control{:type => "text"}/
%label{:for => "name"} Name
%input.form-control{:type => "text"}/
%label{:for => "password"} Password
%input.form-control{:type => "text"}/
%label{:for => "password-confirmation"} Password confirmation
%input.form-control{:type => "text"}/
.col-md-3
.panel.panel-default
.panel-heading Shipping Address
.panel-body
.col-md-6
%label{:for => "name"} Name
%input.form-control{:type => "text"}/
%label{:for => "city"} City
%input.form-control{:type => "text"}/
%label{:for => "zipcode"} Zipcode
%input.form-control{:type => "text"}/
.col-md-6
%label{:for => "address"} Address
%input.form-control{:type => "text"}/
%label{:for => "state"} State
%input.form-control{:type => "text"}/
%label{:for => "country"} Country
%input.form-control{:type => "text"}/
.panel.panel-default
.panel-heading
%h3.panel-title Card information
.panel-body
.row
.col-md-6
%label{:for => "name"} Card Number
%input.form-control{:type => "text", "data-stripe" => "number"}/
.col-md-3
%label{:for => "name"} CVC
%input.form-control{:placeholder => "Ex. 331", :type => "text", "data-stripe" => "cvc"}/
.col-md-3
= label_tag :card_month, "Expiration"
= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month", "data-stripe" => "exp-month"}
= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year", "data-stripe" => "exp-year"}
.text-center
%h2.total-amount
Total:
$0.00
%input{:name => "terms", :type => "CHECKBOX"}>/
Agree to terms?
%br/
%br
%span.payment-errors
%input{:name => "store_front", :type => "hidden", :value => #store_front.id}/
.text-center
%button.btn.btn-primary{:type => "submit"} Pay Now!
.modal-footer
%button.btn.btn-default{"data-dismiss" => "modal", :type => "button"} Close
My stripe params come through just fine. But this is the result of checking my submitted params:
>> params
=> {"utf8"=>"✓", "authenticity_token"=>"xkgz3HdfwqS0/AfKpQteT1FaJE/LMhMneUKETCug47qhlw=", "order_products"=>[{"product_id"=>"37", "quanity"=>"0"}, {"product_id"=>"38", "quanity"=>"1"}], "switchName1"=>"on", "custom-amount"=>"", "store_front"=>"34", "stripeToken"=>"token", "action"=>"create", "controller"=>"orders"}
Does anyone know why my inputs aren't submitting?
You've forgotten the name attribute for each one of your input elements.
Change:
%input.form-control{:type => "text"}/
to:
%input.form-control{:type => "text", :name =>"email"}/
and set the correct value for each one of your elements.
You have specified you field for lable but not your input so add that
%label{:for => "email"} Email Address
%input.form-control{:email, :type => "text"}/

Rails 2 and ajax - few select lists

I can't figure what i do wrong. I have few select lists:
Regions
Towns
Organizations
How it should works:
User selects region.
List of towns loads.
User selects town.
List of organizations loads.
User chooses organization.
I use ajax for that and i realized only auto-loading for list of towns and i can't do same thing for organization. Second select list DOESN'T POST at all!
Here is my code:
View
%div
%br/
= select 'ajax', :region_id, [['Choose your region...', -1]] + Region.all.map{|region| [region.name, region.id]}.sort
= image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
= observe_field :ajax_region_id, :url => { :controller => :organizations, :action => :list_towns, :preselect => (defined?(preselect) && !preselect.nil?) }, :with => 'region_id', :update => 'select_organization_idd', :loading => '$("ajax-progress").show();', :complete => 'if (Ajax.activeRequestCount == 1) $("ajax-progress").hide();'
%br/
= select 'ajax2', :o_id, [], {}, {:id => 'select_organization_idd', :style => 'width: 60em;'}
= image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
= observe_field :ajax_region2_id, :url => { :controller => :organizations, :action => :list_region, :preselect => (defined?(preselect) && !preselect.nil?) }, :with => 'o_id', :update => 'select_organization_idd2', :loading => '$("ajax-progress").show();', :complete => 'if (Ajax.activeRequestCount == 1) $("ajax-progress").hide();'
= f.select :organization_id, [], {}, {:id => 'select_organization_idd2', :style => 'width: 60em;'}
Controller
def list_region
render :text => ActionController::Base.helpers.options_for_select((params[:preselect] ? [['Choose organization', -1]] : []) + Organization.map{|org| [ActionController::Base.helpers.truncate(org.name, :length => 155), org.id]})
end
def list_towns
region = Region.find(params[:region_id])
towns = Kladr.find(:all, :conditions => ['code LIKE ?', "#{region.code}%"])
render :text => ActionController::Base.helpers.options_for_select([['Choose town', -1]] + towns.map{ |t| ["#{t.socr}. #{t.name}", t.id] })
end
What do i do wrong? Also i use Rails 2, that why observe_field is not deprecated.
Do you use rails 3? The method observe_field is deprecated.
With rails 3 you must do something like this :
view
%div
%br/
= select 'ajax', :region_id, [['Choose your region...', -1]] + Region.all.map{|region| [region.name, region.id]}.sort, {}, {:id => 'ajax1'}
= image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
%br/
= select 'ajax2', :o_id, [], {}, {:id => 'select_organization_idd', :style => 'width: 60em;'}, {}, {:id => 'ajax2'}
= image_tag('ajax-loader.gif', :id => 'ajax-progress', :style => 'display: none;')
= f.select :organization_id, [], {}, {:id => 'select_organization_idd2', :style => 'width: 60em;'}
javascript.js.coffee
$('#ajax1').change = () ->
$.post(
url: '/organizations/list_towns'
data: {value: $('#ajax1').val()}
success: () ->
if (Ajax.activeRequestCount == 1)
$("ajax-progress").hide()
)
$('#ajax2').change = () ->
$.post(
url: '/organizations/list_regions'
data: {value: $('#ajax2').val()}
success: () ->
if (Ajax.activeRequestCount == 1)
$("ajax-progress").hide()
)
The implementation is probably wrong and could be refactored. I didn't test it. But you've got the idea.

Resources