PG error using rails where - ruby-on-rails

I have simple query like
User.where('(zone_id IN (?) AND zone_type = "Org") OR (zone_id = ? AND zone_type ="Com")', [1,2,3], 10)
This throws me
PG::UndefinedColumn: ERROR: column "Org" does not exist
What am i doing wrong?

Apparently replacing all conditions fixes the problem:
User.where('(zone_id IN (?) AND zone_type = "?") OR (zone_id = ? AND zone_type ="?")', [1,2,3], "Org", 10, "Com")
I would suggest following solition, which is more readable:
User.where(zone_id: [1,3,5] AND zone_type:"org").or.where(zone_id: 10 AND zone_type: "com")

More Rails way,
You don't have to use IN operator
User.where(zone_id: [1,3,5] AND zone_type:"org").or.where(zone_id: 10 AND zone_type: "com")

Related

ActiveRecord: Find where column is nil or empty array

I have an array column in postgres and I want to find all the records where this column is either nil or []. I can search one or the other fine but trying both fails.
This is what I attempted
Model.where(column: [nil, []])
But I get the error
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal: "{NULL,{}}")
DETAIL: Unexpected "{" character.
This worked for me
Model.where('column IS NULL OR column = ?', '{}')
Model.where("column = ? OR column = ?", nil, [])
This will execute SQL query
SELECT "models".* FROM "models" WHERE (column = NULL OR column = NULL)
But you need can do this only by
Model.where("column = ?", nil)

User Lower Function in where condition in searchkick

#ankane
How can i use postgres lower function in searchkick's where condition
I have below query which is working fine
klass.search(#params[:query], fields: [:name,:category_name],where: {or: [[{available_cities_name: "New Yo"},{available_cities_short_name: "NY"}]]}).hits
Now i want to use lower function but i am getting syntax error
klass.search(#params[:query],
fields: [:name,:category_name],
where: {
or: [ [
{"lower(available_cities_name) = ?", "New Yo"},
{"lower(available_cities_short_name) = ?", "ny"}
]]
}
).hits
I am getting below syntax error,
SyntaxError: unexpected '}', expecting end-of-input
e_cities_name) = ?", "New Yo"},{"lower(available_cities_shor
Can somebody tell me how to use lower function in searchkick ?
Elasticsearch does not have a lower function. To get around this, you can index a lowercase version of the field and query against that.
def search_data
{
available_cities_name: available_cities_name,
available_cities_name_lower: available_cities_name.downcase
}
end
There are two ways to pass args to part of your query. The first is to use hash-syntax eg: {arg_name: 'expected_value'} and the second is array-syntax: ["arg_name = ?", 'expected_value']
Your bug is that you are using array-syntax, but trying to pass it as a hash. ie: {"arg_name = ?", 'expected_value'} which is invalid syntax.
Instead try:
klass.search(#params[:query],
fields: [:name,:category_name],
where: {
or: [
["lower(available_cities_name) = ?", "New Yo"],
["lower(available_cities_short_name) = ?", "ny"]
]
}
).hits
or even just:
klass.search(#params[:query],
fields: [:name,:category_name],
where: ["lower(available_cities_name) = ? OR lower(available_cities_short_name) = ?", "New Yo", "ny"]
).hits
(Note: all code needs to be bug-tested before running).

Why am I getting an undefined method '<=' for in my ROR app

Question I have a custom divide and conquer array sorter that I would like to use. This all works well until I try to use it on an array in my controller I get this message.. NoMethodError (undefined method '<=' for #<Entry:0x0000000ac7d850>): Any help would be greatly appreciated thank you!
here is my Entry model with the mergesort method I am calling in my controller.
def self.mergesort(container)
return container if (container.size <= 1)
mid = container.size / 2
left = container[0...mid]
right = container[mid...container.size]
merge(mergesort(left), mergesort(right))
end
def self.merge(left, right)
sorted = []
until left.empty? or right.empty?
(left.first <= right.first) ? sorted << left.shift : sorted << right.shift
end
sorted + left + right
end
Here is my Entry controller where I am trying to call it.
def pending_sort
#ent_sort = Entry.where("section = ? and approve_disapprove = ?", #mgr_section, '3')
#ent = Entry.mergesort(#ent_sort)
end
You probably have a nil for the first element of either left or right.
irb(main):001:0> left = []
=> []
irb(main):002:0> right = [1]
=> [1]
irb(main):003:0> left.first
=> nil
irb(main):004:0> left.first <= right.first
NoMethodError: undefined method `<=' for nil:NilClass
from (irb):4
from /usr/bin/irb:11:in `<main>'
You can fix the error by casting the nil to a different value. For example, if the values you are comparing are always integers you can change the following line:
(left.first <= right.first) ? sorted << left.shift : sorted << right.shift
to this:
(left.first.to_i <= right.first.to_i) ? sorted << left.shift : sorted << right.shift
But think about how it will affect your functionality... it may break something if it isn't what you actually want to do.

passing a condition to Model.where to find records in rails

I have an instance in a method that is like this
#existinguser = User.where("trial_account_made_by = !nil? ")
I want to return all users where the trial_account_made_by ( a column in users table) is not nil. How do I pass that to where?
Try with trial_account_made_by is not null as:
#existinguser = User.where("trial_account_made_by is not null")
For Rails 4.x, use
#existinguser = User.where.not(trial_account_made_by: nil)
For Rails 3.x, use
#existinguser = User.where('trial_account_made_by is not null')

ActiveRecord : ordering the output of a where request

I'm trying to order the output of a where ActiveRecord query :
result = Class.where('a = ? AND b = ?', params[:a], params[:b])
I tried chaining order both before and after without succeeding, what am I missing ?
#Not working, the order is not modified compared to previous line
result = Class.where('a = ? AND b = ?', params[:a], params[:b]).order('c DESC')
Try to unscope the model, something like
result = Class.unscoped.where('a = ? AND b = ?', params[:a], params[:b]).order('c DESC')
Or delete the default scope if it is not used elsewhere

Resources