I'm new to Rails and I'm using Google Translate to post here. I have a doubt.
I have the following scope:
I'm trying to remove the accent from the bank words when performing a search.
In the parameters it already works with parameterize, but how do I query the bank (inside the where) to remove the accent?
I'm using postgresql.
Initially I tried to use regex_replace, but apparently it didn't work, could I be applying it wrong?
scope :filter_occupation, -> (params) {
params[:occupation].present? ?
where("lower(regexp_replace(occupation, '[^\w]+','')) LIKE ?",
# where("lower(occupation) LIKE ?",
"%#{params[:occupation].parameterize(separator: ' ')}%")
:
all
}
Related
I have words "C&&K", "So`am`I" , "Ant||Man", "A*B==AB", "Ant+Man" in index of azure search.
According to Doc for Escaping special characters + - && || ! ( ) { } [ ] ^ " ~ * ? : \ / I need to prefixing them with backslash (\) And for unsafe and reserved characters need to encode them in URL.
for "C&&K" my search url => /indexes/{index-name}/docs?api-version=2017-11-11&search=C%5C%26%5C%26K~&queryType=full
for "So`am`I" my search url => /indexes/{index-name}/docs?api-version=2017-11-11&search=So%5C%60am%5C%60I~&queryType=full
for "Ant||Man" my search url => /indexes/{index-name}/docs?api-version=2017-11-11&search=A%5C*B%3D%3DAB~&queryType=full
for "A*B==AB" my search url => /indexes/{index-name}/docs?api-version=2017-11-11&search=A%5C*B%3D%3DAB~&queryType=full
for "Ant+Man" my search url => /indexes/{index-name}/docs?api-version=2017-11-11&search=Ant%5C%2BMan~&queryType=full
For all off them I do not get search result. I get "value": []
for "C&&K" I have also tried
url => /indexes/{index-name}/docs?api-version=2017-11-11&search=C%5C%26%26K~&queryType=full
url => /indexes/{index-name}/docs?api-version=2017-11-11&search=C%26%5C%26K~&queryType=full
for "So`am`I" I have also tried
url => /indexes/{index-name}/docs?api-version=2017-11-11&search=So%60am%60I~&queryType=full
It does not work. What am I doing wrong here?
With standard analysis, all of these would be indexed as multiple terms. Fuzzy queries, however, are not analyzed, so it will attempt to find it as a single term. That is, when you index "Ant||Man", after analysis, you end up with the terms "ant" and "man" in the index. When you search for Ant||Man, it will analyze it in much the same way as at index time, but when searching for Ant||Man~, the query won't be analyzed, and since no terms like that exist in the index, you won't get any matches. Similarly, for "A*B==AB" you get the terms "b" and "ab" ("a" is a stop word with default analysis).
So, try the queries without the ~.
In addition to femtoRgon's response, you may want to consider using a custom analyzer that does not index these as multiple terms if you would always like them to be searchable as they are. There is documentation on custom analyzers here, and you can use the Analyze API to test to make sure a given analyzer works as you expect.
I am using neo4j version 3.X, I am using searchkick
currently using
User.search(params[:term], operator: 'or',
fields: [:first_name, :last_name],
misspellings: { below: 5 },
match: :word_start,
page: params[:page], per_page: params[:rpp], padding: params[:offset])
instead of
User.where('(sp.first_name + sp.last_name) =~ ?', /.*#{params[:term].sub(/\s/, '')}.*/i)
But I have problem where I have to make more cypher queries at the same time with searching How to do that?
For exmaple
Neo4j::ActiveBase.new_query.match(n: {User: { uuid: current_user.uuid }}).break
.match('(n)-[:connected_to {status: 2}]-(sp:User)')
.return('DISTINCT sp')
I want to seach in this query with elasctic search with first name & last name
In my model I have defined searchkick word_start: [:first_name, :last_name]
It's been a while since I've used searchkick, but I would suggest trying to use the ActiveNode syntax instead of the neo4j-core Query syntax so that you can append .search on the end:
current_user.connected_users.rel_where(status: 2).distinct.search(...)
This is assuming that there is a connected_users association which uses the connected_to relationship type. You may have another, similar, association in your User model but I didn't know what it was.
I'm not 100% sure if the distinct will work with the search or not, but you could perhaps drop the .distinct part and searchkick might return you a distinct set anyway.
I'm in the Rails console and I want to generate a list of user names that have a trailing whitespace in them. I was thinking that the syntax would look like this, but it didn't work. Any change a better programmer than me can point out what I'm doing wrong?
> User.name.where("% ")
Don't know if you're using MySQL, but an approach would be:
User.where("name LIKE '% '")
You may change this according to your database. This is kinda slow, though.
One way is
Job.all.select{|j| j =~ /^\d+$/}
but it may not be as efficient as the MySQL version.
Another possibility is to use a named scope to hide the ugly SQL:
named_scope :all_digits, lambda { |regex_str|
{ :condition => [" invoice_number REGEXP '?' " , regex_str] }
}
Then you have Job.all_digits.
Answer taken from How to specify Ruby regex when using Active Record in Rails?
You can have
regex_str = "\w+\s+$"
Thanks
Here's what I went with:
User.all.select { |c| c.name.end_with?(" ") }
This got me the list I needed.
It's based on Paritosh's first answer. I'm making his a the canonical answer because I think it's a better resource in general. My solution only helps me, but his has a lot of strategies that would be helpful.
I previously asked a question regarding pulling specific items out of a database if they contained a specific word in their string, someone kindly offered the following which did just the job:
def SomeModel < ActiveRecord::Base
scope :contains_city,
lambda { |city| where("some_models.address LIKE ?","%"+city+"%" ) }
end
However, I have some instances where I would like to do the opposite, i.e. pull out all the items which do not have the specified word in their string. Is there a way to do a NOT LIKE function? I have prevously seen people use '!=' for a NOT EQUALS, but have had no success along these lines for the LIKE function. Is there an equivalent or is it best to iterate through the database putting items in 2 separate databases based on whether they satisfy the LIKE condition?
You could try NOT LIKE in your query; MySQL supports this.
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html
I'm writing a Rails 3 ActiveRecord query using the "where" syntax, that uses both the SQL IN and the SQL OR operator and can't figure out how to use both of them together.
This code works (in my User model):
Question.where(:user_id => self.friends.ids)
#note: self.friends.ids returns an array of integers
but this code
Question.where(:user_id => self.friends.ids OR :target => self.friends.usernames)
returns this error
syntax error, unexpected tCONSTANT, expecting ')'
...user_id => self.friends.ids OR :target => self.friends.usern...
Any idea how to write this in Rails, or just what the raw SQL query should be?
You don't need to use raw SQL, just provide the pattern as a string, and add named parameters:
Question.where('user_id in (:ids) or target in (:usernames)',
:ids => self.friends.ids, :usernames => self.friends.usernames)
Or positional parameters:
Question.where('user_id in (?) or target in (?)',
self.friends.ids, self.friends.usernames)
You can also use the excellent Squeel gem, as #erroric pointed out on his answer (the my { } block is only needed if you need access to self or instance variables):
Question.where { user_id.in(my { self.friends.ids }) |
target.in(my { self.friends.usernames }) }
Though Rails 3 AR doesn't give you an or operator you can still achieve the same result without going all the way down to SQL and use Arel directly. By that I mean that you can do it like this:
t = Question.arel_table
Question.where(t[:user_id].in(self.friends.ids).or(t[:username].in(self.friends.usernames)))
Some might say it ain't so pretty, some might say it's pretty simply because it includes no SQL. Anyhow it most certainly could be prettier and there's a gem for it too: MetaWhere
For more info see this railscast: http://railscasts.com/episodes/215-advanced-queries-in-rails-3
and MetaWhere site: http://metautonomo.us/projects/metawhere/
UPDATE: Later Ryan Bates has made another railscast about metawhere and metasearch: http://railscasts.com/episodes/251-metawhere-metasearch
Later though Metawhere (and search) have become more or less legacy gems. I.e. they don't even work with Rails 3.1. The author felt they (Metawhere and search) needed drastic rewrite. So much that he actually went for a new gem all together. The successor of Metawhere is Squeel. Read more about the authors announcement here:
http://erniemiller.org/2011/08/31/rails-3-1-and-the-future-of-metawhere-and-metasearch/
and check out the project home page:
http://erniemiller.org/projects/squeel/
"Metasearch 2.0" is called Ransack and you can read something about it from here:
http://erniemiller.org/2011/04/01/ransack-the-library-formerly-known-as-metasearch-2-0/
Alternatively, you could use Squeel. To my eyes, it is simpler. You can accomplish both the IN (>>) and OR (|) operations using the following syntax:
Question.where{(:user_id >> my{friends.id}) | (:target >> my{friends.usernames})}
I generally wrap my conditions in (...) to ensure the appropriate order of operation - both the INs happen before the OR.
The my{...} block executes methods from the self context as defined before the Squeel call - in this case Question. Inside of the Squeel block, self refers to a Squeel object and not the Question object (see the Squeel Readme for more). You get around this by using the my{...} wrapper to restore the original context.
raw SQL
SELECT *
FROM table
WHERE user_id in (LIST OF friend.ids) OR target in (LIST OF friends.usernames)
with each list comma separate. I don't know the Rails ActiveRecord stuff that well. For AND you would just put a comma between those two conditions, but idk about OR