2009-06-12 3 views
7

Я хочу, чтобы это SQL-запрос должен быть записан в контроллере рельсы, используя поиск:Rails SQL запросов с находкой

select id,name from questions 
where id not in (select question_id from levels_questions where level_id=15) 

Как я буду это делать? Я использую Rails framework и MySQL. Спасибо заранее.

ответ

21

Простой способ:

ids = LevelsQuestion.all(:select => "question_id", 
     :conditions => "level_id = 15").collect(&:question_id) 
Question.all(:select => "id, name", :conditions => ["id not in (?)", ids]) 

Один выстрел:

Question.all(:select => "id, name", 
:conditions => ["id not in (select question_id from levels_questions where level_id=15)"]) 
+0

можно ли это указать в параметрах_from_collection_for_select в select_tag? – Nave

+1

Я только что отредактировал его, чтобы изменить его от поиска ко всем. Выберите нужную версию. Думаю, что-то заставило тебя передумать. Мне нравится другое решение. Дайте нам знать, почему вы выбрали мой ответ по другому. –

28
Question.find_all_by_sql('select id,name from questions where id not in (select question_id from levels_questions where level_id=15)') 

Это, по общему признанию, не ActiveRecord-иш, но я считаю, что сложные запросы, такие как это, как правило, менее ясно/эффективен при использовании AR макросов. Если вы уже создали SQL, вы можете его использовать.

Некоторые предложения: инкапсулировать этот вызов на поиск методом INSIDE в классе Question, чтобы скрыть данные от контроллера/представления и рассмотреть другие конструкции SQL, которые могут быть более эффективными (например, OUTER JOIN, где levels_questions.question_id имеет значение null)

+0

конечно. это лучше. –

+1

cool ... сначала мой ответ был выбран, тогда я нахожу, что у меня есть -1, и я был вычислен. и теперь автор выбранного ответа говорит, что мой лучше ..? heh, ouch: -} – joshng

+0

хорошо. Я сказал, что твое было лучше, когда я увидел его в первый раз, а не после. Я думаю, что ваш однострочный аппарат выше. Я дал вам +1 за ваш ответ. Я думаю, вам нужно изменить свой ответ, чтобы заменить model.find_by_sql на Question.find_all_by_sql, тогда он будет служить цели автора. –

3

И рельсы 3 способ:

ids = LevelsQuestion.select(:question_id).where(:level_id => 15).collect(&:question_id) 
Question.select(:id, :name).where("id not in (?)", ids) 

 Смежные вопросы

  • Нет связанных вопросов^_^