Rails remove string quotes in pragmatically created where clause - ruby-on-rails

I'm programming User Defined Views in a Rails app. I have a table called uvcondtions that contains the column(field_name), condition(condition), and compared to (ucompare) to information.
For example:
Field_name = description
ucondition = like
ucompare = Truck
Gets turned into where table_name.description like "Truck"
It's working great for most PG SQL conditions. The in condition doesn't work.
If I have this in the uvconditions record:
field_name = id
uvcondition = in
uvcompare = (1,3)
I get this error:
PG::Error: ERROR: syntax error at or near " '(1,3)' "
LINE 1: ...sts" WHERE "worequests"."tenant_id" = 1 AND (id in '(1,3)')
This is the statements that create the where clause:
uvc = uvcondition.ucompare if uvcondition.ucondition == 'in'
#worequests = Worequest.where( uvcondition.field_name + " " + uvcondition.ucondition + " ?", uvc )
Is there any way to remove the quotes around uvc ??
Thanks for the help!

The error is occuring because uvc is actually a string:
uvc = "(1,3)"
Which misleads Rails to sanitize this string before using it in the SQL query (puttin the extra quotes). Instead of this behavior, Rails should create a list of possible values, made from an Array.
Make uvc a Ruby array and it should solve your problem:
uvc = [1, 3]
#worequests = Worequest.where(uvcondition.field_name + " " + uvcondition.ucondition + " ?", uvc)

Related

cl_http_utility not normalizing my url. Why?

Via an enterpreise service consumer I connect to a webservice, which returns me some data, and also url's.
However, I tried all methods of the mentioned class above and NO METHOD seems to convert the unicode-characters inside my url into the proper readable characters.... ( in this case '=' and ';' ) ...
The only method, which runs properly is "is_valid_url", which returns false, when I pass url's like this:
http://not_publish-workflow-dev.hq.not_publish.com/lc/content/forms/af/not_publish/request-datson-internal/v01/request-datson-internal.html?taskId\u003d105862\u0026wcmmode\u003ddisabled
What am I missing?
It seems that this format is for json values. Usually = and & don't need to be written with the \u prefix. To decode all \u characters, you may use this code:
DATA(json_value) = `http://not_publish-workflow-dev.hq.not_publish.com/lc`
&& `/content/forms/af/not_publish/request-datson-internal/v01`
&& `/request-datson-internal.html?taskId\u003d105862\u0026wcmmode\u003ddisabled`.
FIND ALL OCCURRENCES OF REGEX '\\u....' IN json_value RESULTS DATA(matches).
SORT matches BY offset DESCENDING.
LOOP AT matches ASSIGNING FIELD-SYMBOL(<match>).
DATA hex2 TYPE x LENGTH 2.
hex2 = to_upper( substring( val = json_value+<match>-offset(<match>-length) off = 2 ) ).
DATA(uchar) = cl_abap_conv_in_ce=>uccp( hex2 ).
REPLACE SECTION OFFSET <match>-offset LENGTH <match>-length OF json_value WITH uchar.
ENDLOOP.
ASSERT json_value = `http://not_publish-workflow-dev.hq.not_publish.com/lc`
&& `/content/forms/af/not_publish/request-datson-internal/v01`
&& `/request-datson-internal.html?taskId=105862&wcmmode=disabled`.
I hate to answer my own questions, but anyway, I found an own solution, via manually replacing those unicodes. It is similar to Sandra's idea, but able to convert ANY unicode.
I share it here, just in case, any person might also need it.
DATA: lt_res_tab TYPE match_result_tab.
DATA(valid_url) = url.
FIND ALL OCCURRENCES OF REGEX '\\u.{4}' IN valid_url RESULTS lt_res_tab.
WHILE lines( lt_res_tab ) > 0.
DATA(match) = substring( val = valid_url off = lt_res_tab[ 1 ]-offset len = lt_res_tab[ 1 ]-length ).
DATA(hex_unicode) = to_upper( match+2 ).
DATA(char) = cl_abap_conv_in_ce=>uccp( uccp = hex_unicode ).
valid_url = replace( val = valid_url off = lt_res_tab[ 1 ]-offset len = lt_res_tab[ 1 ]-length with = char ).
FIND ALL OCCURRENCES OF REGEX '\\u.{4}' IN valid_url RESULTS lt_res_tab.
ENDWHILE.
WRITE / url.
WRITE / valid_url.

I need to fix malformed pattern error

I want to replace % signs with a $. I tried doing an escape character () but that didn't work. I am using lua 5.1 and I get a malformed pattern error. (ends in '%') This is bugging me because I don't know how to fix it.
io.write("Search: ") search = io.read()
local query = search:gsub("%", "%25") -- Where I put the % sign.
query = query:gsub("+", "%2B")
query = query:gsub(" ","+")
query = query:gsub("/", "%2F")
query = query:gsub("#", "%23")
query = query:gsub("$", "%24")
query = query:gsub("#", "%40")
query = query:gsub("?", "%3F")
query = query:gsub("{", "%7B")
query = query:gsub("}","%7D")
query = query:gsub("[","%5B")
query = query:gsub("]","%5D")
query = query:gsub(">", "%3E")
query = query:gsub("<", "%3C")
local url = "https://www.google.com/#q=" .. query
print(url)
Output reads:
malformed pattern (ends with '%')
You need to escape % and write %%.
The idiomatic what to do this in Lua is to give a table to gsub:
local reserved="%+/#$#?{}[]><"
local escape={}
for c in reserved:gmatch(".") do
escape[c]=string.format("%%%02X",c:byte())
end
escape[" "]="+"
query = search:gsub(".", escape)

Checking variables exist before building an array

I am generating a string from a number of components (title, authors, journal, year, journal volume, journal pages). The idea is that the string will be a citation as so:
#citation = article_title + " " + authors + ". " + journal + " " + year + ";" + journal_volume + ":" + journal_pages
I am guessing that some components occasionally do not exist. I am getting this error:
no implicit conversion of nil into String
Is this indicating that it is trying to build the string and one of the components is nil? If so, is there a neat way to build a string from an array while checking that each element exists to circumvent this issue?
It's easier to use interpolation
#citation = "#{article_title} #{authors}. #{journal} #{year}; #{journal_volume}:#{journal_pages}"
Nils will be substituted as empty strings
array = [
article_title, authors ,journal,
year, journal_volume, journal_pages
]
#citation = "%s %s. %s %s; %s:%s" % array
Use String#% format string method.
Demo
>> "%s: %s" % [ 'fo', nil ]
=> "fo: "
Considering that you presumably are doing this for more than one article, you might consider doing it like so:
SEPARATORS = [" ", ". ", " ", ";", ":", ""]
article = ["Ruby for Fun and Profit", "Matz", "Cool Tools for Coders",
2004, 417, nil]
article.map(&:to_s).zip(SEPARATORS).map(&:join).join
# => "Ruby for Fun and Profit Matz. Cool Tools for Coders 2004;417:"

How to find out the starting point for each match in ruby

Say, i have a following string
string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "
I want o/p as
"#Sachin|0|7;#Tendulkar|29|10;#Sachinn|63|7;"
I tried following
new_string = ""
string.scan(/#\S+/).each{|match| new_string+="#{match}|#{string.index(match)}|#{match.length};" }
which gives me
"#Sachin|0|7;#Tendulkar|29|10;#Sachin|0|7;"
So how i will get the starting index of each sub-string?
This is actually quite a non-trivial task, and has been discussed quite a bit in other questions on SO. This is the most common solution:
string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "
new_string = string.to_enum(:scan,/#\S+/i).inject(''){|s,m| s + "#{m}|#{$`.size}|#{m.length};"}
Here's one that uses scan:
offset = 0
string.scan(/(#\S*)([^#]*)/).map{|m| v = "#{m[0]}|#{offset}|#{m[0].length};"; offset += m.join.length; v}.join
#=> "#Sachin|0|7;#Tendulkar|29|10;#Sachin|63|7;"
Based on this thread How do I get the match data for all occurrences of a Ruby regular expression in a string? just quick example:
string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "
new_string = ""
string
.to_enum(:scan, /#\S+/)
.each do |wrd|
m = Regexp.last_match
new_string += "#{wrd}|#{m.offset(0)[0]}|#{wrd.length};"
end
p new_string

lua Hashtables, table index is nil?

What I'm currently trying to do is make a table of email addresses (as keys) that hold person_records (as values). Where the person_record holds 6 or so things in it. The problem I'm getting is that when I try to assign the email address as a key to a table it complains and says table index is nil... This is what I have so far:
random_record = split(line, ",")
person_record = {first_name = random_record[1], last_name = random_record[2], email_address = random_record[3], street_address = random_record[4], city = random_record[5], state = random_record[6]}
email_table[person_record.email_address] = person_record
I wrote my own split function that basically takes a line of input and pulls out the 6 comma seperated values and stores them in a table (random_record)
I get an error when I try to say email_table[person_record.email_address] = person_record.
But when I print out person_record.email_address it's NOT nil, it prints out the string I stored in it.. I'm so confused.
function split(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
The following code is copy and pasted from your example and runs just fine:
email_table = {}
random_record = {"first", "second", "third"}
person_record = {first_name = random_record[1], last_name = random_record[1], email_address = random_record[1]}
email_table[person_record.email_address] = person_record
So your problem is in your split function.
BTW, Lua doesn't have "hashtables". It simply has "tables" which store key/value pairs. Whether these happen to use hashes or not is an implementation detail.
It looks like you iterating over some lines that have comma-separated data.
Looking at your split function, it stops as soon as there's no more separator (,) symbols in particular line to find. So feeding it anything with less than 3 ,-separated fields (for very common example: an empty line at end of file) will produce a table that doesn't go up to [3]. Addressing any empty table value will return you a nil, so person_record.email_address will be set to nil as well on the 2nd line of your code. Then, when you attempt to use this nil stored in person_record.email_address as an index to email_table in 3rd line, you will get the exact error you've mentioned.

Resources