Replace Umlauts in Ruby on Rails - ruby-on-rails-3

i call a method before i save data and want to replace umlauts in a string like so:
def replace_chars
self.slug = self.slug.gsub(/[äöüß]/) do |match|
case match
when "ä" 'ae'
when "ö" 'oe'
when "ü" 'ue'
when "ß" 'ss'
end
end
end
my problem is, that i want to save the new string into the slug.
how can i do this?
Thanks a lot,
Peter

You can save a little bit of code by using gsub!. I also added the then's to make it (I believe) 1.9 compliant.
def replace_chars
self.slug.gsub!(/[äöüß]/) do |match|
case match
when "ä" then 'ae'
when "ö" then 'oe'
when "ü" then 'ue'
when "ß" then 'ss'
end
end
end

Related

Escaping single quotes in string

Wasnt really sure how to phrase this title, every time I think I have this figured out it always comes back to trip me up.
I am using B1 Boyum and storing a string in a variable.
The code looks like this
#STORE30 = '(T3.ItmsGrpNam LIKE 'Comm%%' OR T3.ItmsGrpNam = 'Vended Ancillary' OR T3.ItmsGrpNam = 'Merchant Fee and CC' OR T3.ItmsGrpNam = 'Laundry P&A')'
However this gives me unexpected END errors, ive tried escaping with + on either side of the first one ('Comm%%') which doesnt give me the unexpected end error but stops the string at T3.ItmsGrpNam LIKE
I need to have the whole string including the apostrophes of each of in between.
One day I will get the hang of this, happy to read some resources on best practices if someone can also supply some links.
Did you try this?
#Store30 = '(T3.ItmsGrpNam LIKE ''Comm%%'' OR T3.ItmsGrpNam = ''Vended Ancillary'' OR T3.ItmsGrpNam = ''Merchant Fee and CC'' OR T3.ItmsGrpNam = ''Laundry P&A'')'
When you want to escape the single quotes just use a double single quotes there.
Figured it out
#STORE30 = SQL(SELECT 'T3.ItmsGrpNam LIKE ''Comm%%'' OR T3.ItmsGrpNam = ''Vended Ancillary'' OR T3.ItmsGrpNam = ''Merchant Fee and CC'' OR T3.ItmsGrpNam = ''Laundry P&A''')

how do i get a rails WHERE query to be more specific? "Like" works, = doesn't

I am very new to Rails and am trying to create a search field to query my database. When I use the WHERE method and use "like", it works, but it's far too broad. If a person's last name is Smith, and I search for "i", it will return Smith as that string contains an "i". How can I make it more specific? I've searched around, read the docs and thought the following should work, but it doesn't return records.
this works
def self.search(query)
where("last_name like ? OR email like ?", "%#{query}%", "%#{query}%")
end
this does not
def self.search(query)
where("last_name = ? OR email = ?", "%#{query}%", "%#{query}%")
end
You're going to want to look more into SQL, as this is very specifically an SQL question. The % operator in SQL returns a fuzzy match. You want a strict match. So
def self.search(query)
where("last_name = ? OR email = ?", query, query)
end
or more succinctly:
scope :search, ->(query) { where('last_name = :query OR email = :query', query: query) }

how do I make this search both first names and last names?

I have this search function:
def self.search(query)
where('customer_phone_number LIKE ? OR lower(first_name) LIKE ? OR lower(last_name) LIKE ?', "%#{query.downcase}%", "%#{query.downcase}%", "%#{query.downcase}%")
end
which is great but if someone types a first AND last name into the search bar, nothing gets returned. how do I make it check the full name if the user enters both a first and last name?
use sql function concat()
def self.search(query)
where("customer_phone_number LIKE ? OR lower(first_name) LIKE ? OR lower(last_name) LIKE ? OR concat(lower(first_name),' ', lower(last_name)) like ?", "%#{query.downcase}%", "%#{query.downcase}%", "%#{query.downcase}%", "%#{query.downcase}%")
end

Protecting against sql injection using activerecord

Following on the question how can I use like query in ruby with sinatra? I have the following problem securing my sql from injection.Here is my method to make a query from the type string, it receives a v(alue) to search for and a k(ey) (=field) to look in.
After that the various selctions are joined by selection.join(' and ')
def string_selector(k, v)
case
when v[/\|/]
v.scan(/([^\|]+)(\|)([^\|]+)/).map {|p| "lower(#{k}) LIKE '%#{p.first.downcase}%' or lower(#{k}) LIKE '%#{p.last.downcase}%'"}
when v[/[<>=]/]
v.scan(/(<=?|>=?|=)([^<>=]+)/).map { |part| p part; "#{k} #{part.first} '#{part.last.strip}'"}
else
# "lower(#{k}) LIKE '%#{v.downcase}%'" #(works)
("lower(#{k}) LIKE ?", '%#{v.downcase}%') #doesn't work
end
end
But i get the error
selectors.rb:38: syntax error, unexpected keyword_end, expecting $end
from C:/../1.9.1/rubygems/core_ext/kernel_require.rb:55:in `require'
What could i be doing wrong ?
There's got to be a better way to do what you are trying to do if you are using ActiveRecord... However, if you need to support your string_selector functionality for some reason, I would at least use Arel:
def string_selector(k, v)
tbl = Arel::Table.new(:test) # your table, or you could pass this in...
condition = case v
when /\|/
vals = v.split(/\|/)
first = vals.shift
vals.inject(tbl[k].matches("%#{first.strip}%")) do |acc, val|
acc.or(tbl[k].matches("%#{val.strip}%"))
end
when /<>/
tbl[k].not_eq(v.gsub(/<>/, '').strip)
when /\=/
tbl[k].eq(v.gsub(/\=/, '').strip)
else
tbl[k].matches(v.strip)
end
tbl.where(condition).to_sql
end
Please note that matches will perform a case insensitive query for you (e.g., by using ILIKE in PostgreSQL).

Rails Active Record Search - Name includes a word

Im trying to pull all records from a Project model that includes in the project_name the word 'Fox'. I can do an active record search and return specific project_names, like 'Brown Fox':
#projects = Project.where("project_name like ?", "Brown Fox")
But if I want to return all the names that INCLUDE 'Fox', this does not work unless the complete project name is 'Fox':
#projects = Project.where("project_name like ?", "Fox")
How do I do a search that returns all the objects with the word 'Fox' in the name?
Try using:
variable = "Fox"
Project.where("project_name like ?", "%#{variable}%")
You can use the SQL % operator:
#projects = Project.where("project_name like ?", "%Fox%")
Note that if you want your query to return results ignoring the word case, you can use PostgreSQL ilike instead of like.
Did you try ransack ?
With ransack you can do something like
#projects = Project.search(:project_name_cont => "Fox")
If you think it is too much for what you need. you can use the % operator as MurifoX said
Here's a version that will allow you to handle any number of input words and to search for all of them within a name. I was looking for this answer and didn't find the more complicated case, so here it is:
def self.search(pattern)
if pattern.blank? # blank? covers both nil and empty string
all
else
search_functions = []
search_terms = pattern.split(' ').map{|word| "%#{word.downcase}%"}
search_terms.length.times do |i|
search_functions << 'LOWER(project_name) LIKE ?'
end
like_patterns = search_functions.join(' and ')
where("#{like_patterns}", *search_terms)
end
end