Ruby or Rails: PG Data Query Error, - ruby-on-rails

I'm trying to update a few records based on a user entered string - it won't let me and produces this error:
PGError: ERROR: invalid input syntax for type boolean: "ian"
LINE 1: UPDATE "subjects" SET treatment_group = 'ian' AND pref_rand ...
I double checked the type from the rails console:
Subject.column_hash["treatment_group"].type
=> :string
And the input method is:
Group Name: <%= text_field_tag(:treatment_group_name) %>
Finally, within the controller I have this logic:
#group_to_randomize = Subject.where("study_site = ? AND treatment_group is null", params[:site_input].to_i).order("created_at ASC").limit(params[:group_size_input].to_i)
flash[:notice] = "We are at the database level. #{#group_to_randomize.inspect}"
if params[:treatment_group_name] != '' and params[:site_input] != '' and params[:group_size_input] != ''
#group_to_randomize.update_all(["treatment_group = ? AND pref_rand = ?", params[:treatment_group_name, #treatment.to_i])
flash[:notice] = "Subjects randomized, and assigned to group #{params[:treatment_group_name]}"
else
flash[:notice] = "Nothing saved, please fill in the form completely."
end
So that it's easier to read, the error stems from this line:
#group_to_randomize.update_all(["treatment_group = ? AND pref_rand = ?", params[:treatment_group_name], #treatment.to_i])
So I can't figure out why it thinks the input is a boolean, and why it won't save as a string anyway. Any help would be greatly appreciated.

because of syntax error, modify this line
#group_to_randomize.update_all(treatment_group:params[:treatment_group_name], pref_rand: #treatment.to_i)

Related

Rails: How to access session parameter / ActiveRecord::StatementInvalid in Orders#create

I am working on a multistep form for an order placement section which uses a session session[:order_params] to store all form inputs before submit.
I need to be able to access a particular parameter (land) from the session in order to query for another resource (shippingservice) when navigating back in the form.
In my orders_controller.rb I have:
#shippingservices = #cart.available_shipping_services.joins(:lands).where(:lands => {:id => params[:id]})
but would need to specify the land.id from the session[:order_params].
When using session[:order_params] I get ActiveRecord::StatementInvalid in Orders#create:
Mysql::Error: Unknown column 'id.ship_to_last_name' in 'where clause': SELECT `shippingservices`.* FROM `shippingservices`
INNER JOIN `zones` ON `zones`.`id` = `shippingservices`.`zone_id`
INNER JOIN `lands_zones` ON `lands_zones`.`zone_id` = `zones`.`id`
INNER JOIN `lands` ON `lands`.`id` = `lands_zones`.`land_id`
WHERE `id`.`ship_to_last_name` = 'Smith'
AND `id`.`ship_to_address` = 'Somewherestreet'
AND `id`.`ship_to_city` = 'Nowheretown'
AND `id`.`ship_to_postal_code` = '99999'
AND `id`.`phone_number` = 'some number'
AND `id`.`shippingservice_id` = '34'
AND `id`.`email` = 'someone#example.tld'
AND `id`.`land_id` = '85'
AND `id`.`ship_to_first_name` = 'John'
AND (weightmin <= 200 AND weightmax >= 200 AND heightmin <= 12 AND heightmax >= 12 AND shippingservices.shippingcarrier = '1') AND (lengthmax >= 210 AND widthmax >= 149)
Since the correct land_id is present I am wondering how to provide only that value to the query.
Thank you in advance!
As per the description mentioned in the post, you want to access a particular key stored in session at a particular key.
Assuming order_params is a hash, you can get land_id using the below mentioned code:
session[:order_params][:land_id]
This will return the value of land_id and thus you can use it in the query.
To set session variable, you can set some data in a controller action
For eg:
app/controllers/sessions_controller.rb
def create
# ...
session[:current_user_id] = #user.id
# ...
end
And read it in another: app/controllers/users_controller.rb
def index
current_user = User.find_by_id(session[:current_user_id])
# ...
end

PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer

I am doing a "IN" query using prepared statements on rails. I am getting PG::InvalidTextRepresentation error.
code :
def mark_ineligible(match_ids)
ids = match_ids.join(", ")
result = epr("mark_matches_as_ineligible",
"UPDATE matches SET is_eligibile=false WHERE id IN ( $1 )",
[ids])
end
def epr(statementname, statement, params)
connection = ActiveRecord::Base.connection.raw_connection
begin
result = connection.exec_prepared(statementname, params)
return result
rescue PG::InvalidSqlStatementName => e
begin
connection.prepare(statementname, statement)
rescue PG::DuplicatePstatement => e
# ignore since the prepared statement already exists
end
result = connection.exec_prepared(statementname, params)
return result
end
end
trying to invoke this using :
match_ids = [42, 43]
mark_ineligible match_ids
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "42, 43"
from (irb):24:in `exec_prepared'
from (irb):24:in `rescue in epr'
from (irb):15:in `epr'
from (irb):8:in `mark_ineligible'
from (irb):35
Please help here. I want to know why I am getting this errors and how to fix it.
Thanks,
mark_ineligible should look as follows:
def mark_ineligible(match_ids)
result = epr("mark_matches_as_ineligible",
"UPDATE matches SET is_eligibile=false WHERE id IN ( $1 )", match_ids)
end
And when you call mark_ineligible, pass an array as argument:
mark_ineligible(match_ids) #=>match_ids = [42,43]

Conditionally add OR condition in query

The orders table have a few columns, say email, tel and address.
User provides email/tel/address, and any of them can be nil or empty string (EDITED).
How to generate an OR query, so if any of the columns match, the record is returned?
The only catch is that if any value provided is nil or empty, that will be ignored instead.
I was able to do the following using Arel:
email = params[:email]
tel = params[:tel]
address = params[:address]
t = Order.arel_table
sq = t[:email].eq(email) if email.present?
sq = sq.or(t[:phone].eq(phone)) if phone.present?
sq = sq.or(t[:phone].eq(address)) if address.present?
Order.where( sq )
However it will err if email is nil, because sq will not instantiate.
I want to prevent constructing sql string, and I use Squeel gem.
you can put
Order.where("email=? or tel= ? or address=?", params[:email], params[:tel], params[:address])
You can check whether your params are nil or not by Ick's maybe. So read about Ick gem and follow the steps given there and then you can use it in your case like :
params[:email].maybe
params[:tel].maybe
params[:address].maybe
Hope, this is what you were looking for.
Please have a try with
where_condition = "true"
where_condition += "OR email = '#{params[:email]}'" if params[:email].present?
where_condition += "OR tel = '#{params[:tel]}'" if params[:tel].present?
where_condition += "OR address = '#{params[:address]}'" if params[:address].present?
Order.where(where_condition)
In order to prevent nil or empty string, I finally got the following:
t = Order.arel_table
conditions = [:email, :phone, :address].map{|attr|
attr_value = params[attr]
if attr_value.present?
t[attr].eq(attr_value)
else
nil
end
}.compact
if conditions.empty?
Order.where('1=0')
else
Order.where( conditions.inject{|c, cc| c.or(cc).expr} )
end
Ugly, but flexible.

Ruby on Rails array delete_if block, string is "missing translation: no key" inside but fine outside

My problem is that the print t inside the delete_if block prints 'translation missing: en.no key'
This is strange. The error message in the browser shows me my pages parameters.
Here is what is says for tutor_id:
"tutor_id"=>["1", "2"].
I also tried the following inside the block to make sure it was right, and it did indeed return String.
print t.class # => returns 'String'
Also making a call to the following inside the block yields an error
Integer(t) # => yields error: invalid value for Integer(): "translation missing: en.no key"
Likewise, a call to .to_i is not helpful. It always returns 0. Note: this is the behavior o any non-numerical string such as 'hello'.to_s
print t.to_i # always prints '0'
The following is the troublesome code:
#get an array of all tutors' IDs
tutorIds = params[:tutor_id]
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", Integer(t)])
}
Update I left out a bit of information so if the delete_if block is
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", t ])
}
The error I get is:
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "translation missing: en.no key" LINE 1: ...ECT 1 AS one FROM "schedules" WHERE (tutor_id = 'translati... ^ : SELECT 1 AS one FROM "schedules" WHERE (tutor_id = 'translation missing: en.no key') LIMIT 1
Well it was right under my nose. Such a simple mistake. Notice the [] -> ||
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", t ])}
Should have been
tutorIds.delete_if { |t|
print t
Schedule.exists?(["tutor_id = ?", t ])}
Can you try
Schedule.where("tutor_id = ?", t.to_i).exists?
instead?

Railswhat to do about empty columns in my database? Throwing an error:ArgumentError: invalid value for Float(): ""

Im trying to read a column of String values from my DB. Im trying to convert them to floats. I have written the following method to do that
def initialize (db_listings)
db_listings.each do |listing|
name = listing.name
index = listing.id
lat_string = listing.latitude
long_string = listing.longitude
puts "name = #{name}"
puts "index = #{index}"
puts "Converting #{lat_string} to float"
puts "Converting #{long_string} to float"
if(lat_string == nil || long_string == nil )
lat_float = Float(9999)
long_float = Float(9999)
else
lat_float = Float(lat_string)
long_float = Float(long_string)
end
puts "Now printing floats"
puts lat_float
puts long_float
end
end
But I get the following error:
Throwing an error:ArgumentError: invalid value for Float(): ""
This is because it encountered an empty entry for that column.
My question is : WHy did the if else statement in my method not catch it?
How do I adjust my method for empty/invalid values in the database?
Thanks
From the error message I presume lat_string and long_string are empty strings rather than nil. You could use blank? to catch both nil and empty strings:
if(lat_string.blank? || long_string.blank?)
lat_float = Float(9999)
long_float = Float(9999)
else
lat_float = Float(lat_string)
long_float = Float(long_string)
end

Resources