finding where by using IN operator in rails3 - ruby-on-rails-3

I am trying to run a sql like below
select name from appointments where location_id in (2,3,4)
the following does not work. I am using PostgreSQL
a = [2,3,4]
Appointment.select(:name).where("location_id IN ?", a)
ActiveRecord::StatementInvalid: PGError: ERROR: syntax error at or near "2"
LINE 1: ... FROM "appointments" WHERE (location_id IN 2,3,4)
^
: SELECT name FROM "appointments" WHERE (location_id IN 2,3,4)

You can use this:
Appointment.select(:name).where(:location_id => [2,3,4])
Hope this helps

I don't know rails, but it looks to me like you need to do this:
Appointment.select(:name).where("location_id IN (?)", a)
i.e., put brackets around the ?.

Related

rails order parameterized query

I know that order is not safe, so I want to refactor this code:
#tasks = #search.result.joins(user_application_status: {student_application: [student_profile: :student]})
.order(sort_column + ' ' + sort_direction).page(params[:page])
sort_column is reading from params directly and would be something like user_application_tasks.name and sort_direction would return somethig like asc, I tried refactoring it to:
.order("? ?", sort_column, sort_direction).page(page_params)
but I am getting an error
ActiveRecord::StatementInvalid - PG::SyntaxError: ERROR: syntax error at or near ","
LINE 1: ...HERE (application_statuses.id = 137) ORDER BY ? ?, user_app...
I have done this sort of thing before with where statements like
Thing.where("state = ?" ,params[:state])
Is there some special syntax I am omitting?
EDIT:
The thing I am most worried about is someone being able to inject sql here and do something harmful, as #spickermann mentioned order doesn't sanitize the data so
Thing.order("name; drop table users;")
will result in the users table being destroyed.
order doesn't sanitize attributes when they are provided in a list like where does.
But is accepts as hash like this:
order(sort_column => sort_direction)
See the Rails Guides About Ordering.

? in ActiveRecord select

In a where statement, you can use variables like:
Order.where('employee_id = ?', params[:employee_id])
I'm trying to accomplish something similar with a select, but it's not working:
Order.select('amount FROM line_items WHERE employee_id = ? AS employee_line_items', params[:employee_id])
=> ERROR: syntax error at or near "1"
=> LINE 1: ...ployee_id" = ? AS employee_line_items, 1
What's going on here? Is it possible to use ? in select statement? If not, how can you insert an escaped sql string here? I'd like to just use #{params[:employee_id]}, but this bit of code would be vulnerable to sql injection.
You have to split your query and chain it:
Order.select('amount FROM line_items').where(['WHERE employee_id = ?', params[:employee_id]])
And also based on this question, I believe you cannot use AS in WHERE clause, only when selecting fields (and you can't use them in WHERE in any case)
Check the documentation to understand how select works on ActiveRecord models

HibQuerySyntaxException when I use CAST() in query

I am running this hibernate query from my java class.But i am getting QuerySyntaxException.But i didnt find any thing went wrong.
Query
SELECT count(contact.id)
FROM Contact contact
WHERE contact.id IN (
SELECT DISTINCT action.contact
FROM Action action
WHERE action.status = 'O'
AND action.currentAssignee = :currentAssignee)
AND contact.contactStatus IN :contactStatus
AND CAST(contact.id as char(12)) like :id --Note this line
AND contact.issue.productGroup IN :productGroup
But the problem is in using CAST.
The error is :
expecting CLOSE, found '('
Error While getting countOpenContacts. java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: expecting CLOSE, found '('
The following java code has been used to set the id.(contact.id is Long value and contactId is string.)
query.append("AND CAST(contact.id as char(12)) like :id ");
params.put("id",(contactId+ "%"));
Can we CAST in hibernate query?
As documentation says, we can use
cast(... as ...), where the second argument is the name of a Hibernate type
So you should try
AND CAST(contact.id as string) like :id

Active Record query causing SQLException near "," syntax error

I'm trying to display all such rows of a table STUDENTS which have a value of an attribute, such as COURSE IN a set of given values e.g. 'MS', 'PhD'.
I get the values in the students_controller.rb file using params. I tried to run an Active Record query using where to do the job:
#all_courses = ['MS', 'PhD', 'BA', 'MSc']
#students = Student.where("course IN :courses" , {:courses => params.has_key?(:courses) ? params[:courses].keys : #all_courses})
But I get the following error:
SQLite3::SQLException: near ",": syntax error: SELECT "students".* FROM "students" WHERE (course IN 'MS', 'PhD', 'BA', 'MSc')
I think the error might be due to the absence of ; at the end of the SQL query generated by Active Record, but I cannot do anything to get that semicolon at the end.
You need to use parentheses: "course IN (:courses)"

Rails order method; column named :order

I have a model Exercises and it has columns of :circuit and :order (among others). In a view, I am trying to order the Exercises first by :circuit and then by :order. When I use the following:
#schedule.exercises.order(:circuit).each do |exercise|
it works as expected. However, when I try to add the :order column:
#schedule.exercises.order(:circuit, :order).each do |exercise|
I get the following error:
SQLite3::SQLException: near "order": syntax error: SELECT "exercises".* FROM "exercises" WHERE "exercises"."schedule_id" = 1 ORDER BY circuit, order
The same error also occurs when I pass the :order column alone:
#schedule.exercises.order(:order).each do |exercise|
SQLite3::SQLException: near "order": syntax error: SELECT "exercises".* FROM "exercises" WHERE "exercises"."schedule_id" = 1 ORDER BY order
I'm assuming that this is because the column name (:order) is the same as the SQL method name (order). I'm wondering if there's any way around this other than changing my column heading?
Thanks,
Stuart
Changing the column name is the only sensible option out of this. Change it to something like "position".
If you really want to try and do this you could write a find by sql query and escape the col name with back quotes like
ModelName.find_by_sql(SELECT * FROM ModelName ORDER BY '`order`')
But I would say you should just change the column name
I am also facing same issue, but specifying table name in order clause it works.
#schedule.exercises.order("exercises.circuit ASC, exercises.order ASC").each do |exercise|
Just use "reorder" instead of "order"