Как передать данные в запрос IN в рельсах 3 - PullRequest
7 голосов
/ 26 марта 2012

Я работаю над рельсами 3 и sqlite db. Используя запрос IN. В настоящее время передается строковая переменная элементов в запрос IN. Но при выполнении этого запроса требуется «», поэтому он не работает. Как преодолеть эту ситуацию?

Вот мой код

items = ""
items << "#{@invitation_user1.id}" << "," << "#{@invitation_user2.id}" << "," << "#{@user1.id}" << "," << "#{@user2.id}" << "," << "#{@user2.id}" << "," << "#{@profile1.id}" << "," << "#{@profile2.id}"
@activities = Version.where("item_id IN (?)","#{items}") 

Попробовал items.to_i, items.to_s, но не сработало. В журнале я вижу это.

SELECT "versions".* FROM "versions" WHERE (item_id IN ('19,20,4,1,1,4,1'))

Но все, что мне нужно, это

 SELECT "versions".* FROM "versions" WHERE (item_id IN (19,20,4,1,1,4,1))

Ответы [ 3 ]

25 голосов
/ 26 марта 2012

Вы можете просто передать массив. Rails достаточно умен, чтобы с ним справиться:

items = [
  @invitation_user1.id,
  @invitation_user2.id,
  @user1.id,
  @user2.id,
  @profile1.id,
  @profile2.id
]

@activities = Version.where("item_id IN (?)", items)
# or equivalently:
@activities = Version.where(:item_id => items)

Это значительно предпочтительнее вашего варианта, поскольку Rails правильно обрабатывает экранирование всех переданных значений для используемого адаптера базы данных.

1 голос
/ 26 марта 2012

То, что вы ищете, это split :

[1] pry(main)> a = '19,20,4,1,1,4,1'
=> "19,20,4,1,1,4,1"
[2] pry(main)> a.split(',')
=> ["19", "20", "4", "1", "1", "4", "1"]
[3] pry(main)> a.split(',').map(&:to_i)
=> [19, 20, 4, 1, 1, 4, 1]

Но, поскольку вы строите 'строку' вручную, лучше использовать массив:

items = Array.new
items << @invitation_user1.id << @invitation_user2.id << @user1.id
items << @user2.id << @user2.id << @profile1.id << @profile2.id
@activities = Version.where(item_id: items) 

В любом случае, способ получения идентификаторов странный, потому что ... что произойдет, если вы добавите больше пользователей?или профили?

Что бы я сделал (увидев так мало, как мы видим в вашем примере)

items = Array.new
items << get_invitation_user_ids
items << get_user_ids 
items << get_profile_ids
@activities = Version.where(item_id: items)

и позже определю эти методы, как в:

def get_invitation_user_ids
  InvitationUser.select(:id).map(&:id)
end

...
1 голос
/ 26 марта 2012

Использовать массив вместо строки.

Например

ids = [ @invitation_user1.id, @invitation_user2.id, @user1.id, @user2.id ]

Тогда вы легко сможете найти записи по

@versions = Version.find_all_by_id(ids)

Это приведет к ожидаемому запросу.

SELECT "versions".* FROM "versions" WHERE (item_id IN (19,20,4,1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...