Rails 2.3.5
I'm not having any luck searching for an answer on this. I know I could just write out a manual sql statement with a concat in it, but I thought I'd ask:
To load a select, I'm running a query of shift records. I'm trying to make the value in the select be shift date followed by a space and then the shift name. I can't figure out the syntax for doing a concat of two fields in a collect. The Ruby docs make it looks like plus signs and double quotes should work in a collect but everything I try gets a "expected numeric" error from Rails.
#shift_list = [a find query].collect{|s| [s.shift_date + " " + s.shift_name, s.id]}
Thanks for any help - much appreciated.
Hard to say without knowing what s is going to be or what type s.shift_date and s.shift_name are but maybe you're looking for this:
collect{|s| ["#{s.shift_date} #{s.shift_name}", s.id]}
That is pretty much the same as:
collect{|s| [s.shift_date.to_s + ' ' + s.shift_name.to_s, s.id]}
but less noisy.
Related
I am trying to build an auto-populating string to search my database without getting an error message. I am stumped as to how to make " auto-populate as opposed to '.
I have pulled parts of strings from different places online to create this one (as this is way more complicated than what I have ever written) and as a result, I am struggling to edit the part I need.
="'" & join("' OR '",indirect("A2:A"&text(rows(A:A)-countblank(A:A),"0")), "'")
Actual: 'Football' OR 'football'
Intended: "Football" OR "football"
try it like this:
=""""&TEXTJOIN(""" OR """, 1, A2:A)&""""
I want to avoid using injection of parms in the query statement. Therefore we used the following instructions from the NEO4J .NET client class:
var queryClassRelationshipsNodes = client.Cypher
.Start("a", (NodeReference)sourceReference.Id)
.Match("a-[Rel: ***{relationshipType***} ]->foundClass")
.Where("Rel.RelationStartNode =" + "\'" + relationshipStart + "\'")
.AndWhere("Rel.RelationDomainNode =" + "\'" + relationshipDomain + "\'")
.AndWhere("Rel.RelationClassNode =" + "\'" + relationshipClass + "\'")
.WithParam("relationshipType", relationshipType)
.Return<Node<Dictionary<string, string>>>("foundClass")
.Results;
However this code does not work once executed by the server. For some reason the PARM: relationshipType is not connected with the variable which we put in between {}.
Can someone please help us debug the problem with this code? We would prefer to use WithParms rather than injecting variables inside the statement.
Thanks a lot!
Can someone please help us debug the problem with this code?
There's a section on https://bitbucket.org/Readify/neo4jclient/wiki/cypher titled "Debugging" which describes how to do this.
As for your core problem though, your approach is hitting a Cypher restriction. Parameters are for parts of the query that aren't compiled into the query plan. The match clause is however.
From the Neo4j documentation:
Parameters can be used for literals and expressions in the WHERE clause, for the index key and index value in the START clause, index queries, and finally for node/relationship ids. Parameters can not be used as for property names, since property notation is part of query structure that is compiled into a query plan.
You could do something like:
.Match("a-[Rel:]->foundClass")
.Where("type(Rel) = {relationshipType}")
.WithParam("relationshipType", relationshipType)
(Disclaimer: I've just typed that here. I haven't tested it at all.)
That will likely be slower though, because you need to retrieve all relationships, then test their types. You should test this. There's a reason why the match clause is compiled into the query plan.
I'd like to check the first two chars of a number straight in my model. First I define the number of the current logged in user (devise):
user_number = current_user.number.first(2)
then I want to take that value and check it within a where statement in a "number" mobel, so I tried this
#numbers = Number.where(:number_value.first(2) => user_number)
which is obviously the same as
#numbers = Number.where(:number_value.first(2) => current_user.number.first(2))
No, that does not work.
How can I check the first 2 chars of the :number_value column in my model?
Any help is appreciated.
Many thanks.
Solution (SQLite)
#numbers = Number.where("number_value like '" + current_user.number.first(2) + "%'")
since this is not lazy loading I'm not convinced yet that it is the smartest solution. if you know any better, would be cool if you can share
First, you should read the ActiveRecord query guide. I'd also imagine that there's a much more straight forward way for you to accomplish your goal.
But, to answer your specific question, here's an approach that'd work with Postgresql.
Number.where("number_value::text like ?", current_user.number.to_s[0,2] + "%")
what is the best way to escape a Search String from an input field to prevent SQLInjections?
Is there an mysql_real_escape_string method like in PHP or should i manually replace/escape the different characters like: OR, AND, LIKE, WHERE, DELETE, INSERT, UPDATE, FROM, GROUP BY, ORDER BY and so on?
closed with the answer from: #Nick Weaver:
I don't think that you have to take care about that.
Using mysql_real_escape_string for a search query is a good option. However you need to be aware of 2 things :
1) If you apply this solution in an other situation, make sure the parameter is always quoted when it gets integrated. In short, mysql_real_escape_string does not protect you against numeric parameters. Here are 2 examples :
$bad_sql = "SELECT * FROM some_table WHERE id=" . mysql_real_escape_string($_GET['id']);
$good_sql = "SELECT * FROM some_table WHERE name='" . mysql_real_escape_string($_GET['id']) . "'";
2) The second thing to consider is that mysql_real_escape_string does not escape wildcard characters (% and _). You should not worry about that. However, a "perfect" solution escape those characters.
For more information you can take a look at http://www.sqlinjection.net.
FYI : The official mysql_real_escape_string reference http://php.net/manual/en/function.mysql-real-escape-string.php.
I'm trying to return results more like the search
My curren algorithm is this
def search_conditions(column, q)
vars = []
vars2 = []
vars << q
if q.size > 3
(q.size-2).times do |i|
vars2 << q[i..(i+2)]
next if i == 0
vars << q[i..-1]
vars << q[0..(q.size-1-i)]
vars << q[i % 2 == 0 ? (i/2)..(q.size-(i/2)) : (i/2)..(q.size-1-(i/2))] if i > 1
end
end
query = "#{column} ILIKE ?"
vars = (vars+vars2).uniq
return [vars.map { query }.join(' OR ')] + vars.map { |x| "%#{x}%" }
end
If I search for "Ruby on Rails" it will make 4 search ways.
1) Removing the left letters "uby on Rails".."ils"
2) Removing the right letters "Ruby on Rail".."Rub"
3) Removing left and right letters "uby on Rails", "uby on Rail" ... "on "
4) Using only 3 letters "Rub", "uby", "by ", "y o", " on" ... "ils"
Is good to use these 4 ways? There any more?
Why are you removing these letters? Are you trying to make sure that if someone searches for 'widgets', you will also match 'widget'?
If so, what you are trying to do is called 'stemming', and it is really much more complicated than removing leading and trailing letters. You may also be interested in removing 'stop words' from your query. These are those extremely common words that are necessary to form grammatically-correct sentences, but are not very useful for search, such as 'a', 'the', etc.
Getting search right is an immensely complex and difficult problem. I would suggest that you don't try to solve it yourself, and instead focus on the core purpose of your site. Perhaps you can leverage the search functionality from the Lucene project in your code. This link may also be helpful for using Lucene in Ruby on Rails.
I hope that helps; I realize that I sort of side-stepped your original question, but I really would not recommend trying to tackle this yourself.
As pkaeding says, stemming is far too complicated to try to implement yourself. However, if you want to search for similar (not exact) strings in MySQL, and your user search terms are very close to the full value of a database field (ie, you're not searching a large body of text for a word or phrase), you might want to try using the Levenshtein distance. Here is a MySQL implementation.
The Levenshtein algorithm will allow you to do "fuzzy" matching, give you a similarity score, and help you avoid installation and configuration of a search daemon, which is complicated. However, this is really only for a very specific case, not a general site search.
While, were all suggesting other possible solutions, check out:
Sphinx - How do you implement full-text search for that 10+ million row table, keep up with the load, and stay relevant? Sphinx is good at those kinds of riddles.
Thinking Sphinx - A Ruby connector between Sphinx and ActiveRecord.