Concatenation for search in Ruby on Rails - ruby-on-rails

So, as part of a search function in a Ruby on Rails app, I've made Users searchable by first name and last name. However, when I type in their full name, it doesn't render any results. So, if a User is named John Smith, I can type in "John" or "Smith" and it will bring him up, but if I type in "John Smith" it doesn't recognize it.
I know that's because in my search code I only enabled first_name and last_name but not the User's full name. What's the proper way to concatenate the first and last names to solve this problem?
Here's the current code:
users = User.find_by_sql(['select *
from users
where first_name ilike ?
or last_name ilike ?
order by last_name limit ?', q, q, 100])

Check this code,
users = User.find_by_sql(["SELECT * FROM users WHERE (coalesce(users.first_name, '') || ' ' || coalesce(users.last_name, '') ilike '%#{p.downcase}%' )"])

What about mysql concat ?
users = User.find_by_sql(["SELECT * FROM users WHERE
CONCAT(first_name, ' ', last_name) LIKE ?
ORDER BY last_name LIMIT ?", p, 100]
)
where p could be anything John, Smith, John Smith

Related

How to query ActiveRecord for 2 attributes with 1 value

I have a username in this variable invoice.user_name, say John Wayne Doe. I want to find a User based on his/her name. Ideally, I would like to use User.where(name: invoice.user_name). However, my database has 'first_name' and 'last_name', so I can't query based on name. Would it be possible to do something like this: User.where('first_name AND last_name like ?', invoice.user_name')
Or how would I approach that?
Thx
You can do it this way... or at least it works for me using a postgreSQL database...
User.where("CONCAT(first_name, ' ', last_name) = ?", invoice.user_name)

Rails ActiveRecord Query a field based on word contains but not partial word

I know we have LIKE option to search partial word, exact word match and also word contains (but having some problem, let me explain that below)
User.where("name like ?", "%john%")
# above code will search the name column and it will return records even if it
matches the character partially i.e "joh" also return a record.
User.where("name like ?", "john")
# above code will return a record if 'john' word is in the name column.
It will match the exact word.
User.where("name like ?", "% john %")
# this will return a record if name column contains 'john' text i.e "Sample john victor".
But if a record has "John victor" then it won't find this record because '% john %'
can only match middle of the words except first and last word in the name column
since we having space in both front and end of the word in our search i.e "% john %"
Can someone help me to find a record based on word contains in a string of one column in a Table?
You don't specify which database you're using and it's possible different databases allow different forms of matching. E.g. in postgres you could use SIMILAR TO
For a straight SQL LIKE I think you'll need to do several options ORed together.
E.g.
User.where("(name = ?) or (name like ?) or (name like ?) or (name like ?))",
'john'
'% john %',
'john %',
'% john')
That'll get values that are 'john', that inclued 'john', that start with 'john' and that end with 'john' respectively.
That might be pretty slow depending on the data you're querying but I think it'll achieve what you want.

How to execute Model Method name in where query?

I have users table that has first_name and last_name. On my user index page, there is a text field for first_name and last_name search.
If I search with either first_name or last_name it works fine. But if I enter the full name in the text field then it doesn't give me any results
My User model
def fullname
first_name + last_name
end
My Query
User.where("lower(first_name) like ? or lower(last_name) like ?", "%#{params[:fullname].downcase}%", "%#{params[:fullname].downcase}%")
Concatenate the two names when searching:
User.where(
"(LOWER(first_name) || ' ' || LOWER(last_name)) LIKE ?",
"%#{params[:fullname].downcase}%"
)

How to use select....as and concat in rails 5

I have a table called Student, the student table contains the id, first_name and last_name. I am trying to select and concatenate first_name and last_name and display the column as "Name". This is my query:
Student.select("concat(first_name, ' ', last_name) as 'Name'").find(201410204)
but it returns
SELECT concat(first_name, ' ', last_name) as 'Name' FROM `students` WHERE `students`.`id` = 201410204 LIMIT 1
#<Student id: nil>
but when i try to paste the query inside mysql workbench it return the student name that has the id 201410204 and the column name is "Name".
Click to see the result of the query
What's the problem about my code? Thanks
You need to select the id as well:
Student.select(:id, "CONCAT(first_name,' ',last_name) as name").find(201410204)
2.4.1 :073 > Student.select(:id, "CONCAT(first_name,' ',last_name) as name").find(23000)
Student Load (0.9ms) SELECT "students"."id", CONCAT(first_name,' ',last_name) as name FROM "students" WHERE "students"."id" = $1 LIMIT $2 [["id", 23000], ["LIMIT", 1]]
=> #<Student id: 23000, name: "Joe Blow">
Let me give you two solutions, one by using the power of rails and other using the scalability of rails.
1) (Using power of rails)
In the Student model create a method named full_name and concatenate first_name and last_name.
class Student < ActiveRecord::Base
.....
def full_name
"#{try(:first_name)} #{try(:last_name)}".to_s
end
.....
end
Now open console or any where you need,
student = Student.find(201410204)
student.full_name
thats it, you will get the full name.
2) Using Scalability of rails, even can execute SQL queries.
student = ActiveRecord::Base.connection.exec_query("SELECT CONCAT(first_name,' ', last_name) FROM students where students.id = 201410204")
It returns an array,now you can retrieve using,
student.rows[0]
Thats it, you will get the same result.
One solution
In model Create A method
def full_name
"#{self.try(:first_name)} #{self.try(:last_name)}"
end
Now
Student.find(121).full_name
With select you restrict the returned columns. Your query returns only the Column Name. id and all other columns are missing. In this case you get an instance of student where all attributes are nil. Only the attribute Name is set. When you try Student.select("concat(first_name, ' ', last_name) as 'Name'").find(201410204).Name you will see the right result.
When you want to get all attributes you have to extend your select like this Student.select("concat(first_name, ' ', last_name) as 'Name', *").find(201410204)
Edit:
I did check it for mysql on https://de.piliapp.com/mysql-syntax-check/, I don't know why but you have to name * first.
Student.select("*, concat(first_name, ' ', last_name) as 'Name'").find(201410204)

Rails and Postgreql Concatenate space

I have an search field for user with autocomplete, it was working but I migrated my database from mySQL to Postgresql but cannot get the concatenate working. When I type a first name or a last name is working but when my user are typing Firstname Lastname (with a space between them) it's not working anymore and cannot get it working or figure out what to do.
That's my SQL command :
#users = User.find(:all,:conditions => ['(last_name LIKE ? OR first_name LIKE ? OR (first_name || last_name) LIKE ? OR (last_name || first_name) LIKE ?) AND adult = ?', "%#{params[:term]}%", "%#{params[:term]}%", "%#{params[:term]}%", "%#{params[:term]}%", false])
My issue is here : (first_name || last_name) that will return correct value when the user type FirstNameLastName so the concat works here but when I try to add the space I cannot figure out what is wrong I tried :
(first_name ||' '|| last_name) or (first_name ||" "|| last_name)
But none of these will work I found another thread on stackoverflow but cannot get it working and I don't understand why...
Thanks,
No idea about Rails but how about
'....(first_name || \' \' || last_name)...'

Resources