2013-12-24 3 views
1

Я довольно новичок в рельсах. У меня есть следующие моделиЗапрос Rails для моделей, имеющих has_many и принадлежит_от отношения

class Question < ActiveRecord::Base 
    has_many :options 
    has_many :response_parts 
end 

class ResponsePart < ActiveRecord::Base 
    belongs_to :question 
end 

Соответствующие каркасы являются

rails g scaffold Question qorder:string qtext:text qtype:string 

rails g scaffold ResponsePart answer:string question:belongs_to 

Теперь я хочу, чтобы все части ответа, где qtype является «мобильным». Я пробовал несколько способов, но не смог выполнить запрос. Может кто-то сказать способ сделать такой запрос. Заранее спасибо.

ответ

0

Вы можете включить связь между двумя модели и добавить ограничение на нем:

ResponsePart.includes(:question).where(questions: { qtype: 'mobile' }) 

Это будет извлекать все объекты ResponsePart из БД, имеющие вопрос, которые соответствуют «qtype == 'mobile'»

Это также является наиболее эффективным способом, чтобы получить эти записи.


Question.where(qtype: 'mobile').collect(&:response_parts) 

Это будет опрашивать БД, чтобы получить соответствующие response_parts каждого вопроса, имеющих «qtype == 'mobile'» Пример: Если у вас есть 6 вопросов с «qtype == 'mobile'», это создаст 6 запросов SQL для каждого Вопрос.

Question.where(qtype: "mobile").first.response_parts 

Это только извлекает объекты ResponsePart относящиеся к первому вопросу, соответствующие условию «qtype == 'mobile'»

+0

Спасибо. Я получаю '# , # ]> 'когда я запрашиваю' ResponsePart.includes (: question) .where (вопросы: {qtype: 'mobile'}) '. Но теперь я хочу получить доступ к соответствующим значениям ответа. Когда я использую 'ResponsePart.includes (: question) .where (вопросы: {qtype:' mobile '}). Каждый и пытаюсь получить доступ к значениям с использованием .answer, он дает ошибку неопределенный метод 'answer'. Я обращаюсь к значениям неправильно? – Peeyush

+0

Хм, что касается другого вопроса, но мы можем ответить на него здесь. Убедитесь, что вы используете правильную переменную: по вашему мнению, у вас должно быть что-то вроде «ResponsePart.includes (: question) .where (вопросы: {qtype: 'mobile'}). Each do | response_part |' тогда вы должны быть чтобы получить доступ к значению ответа, выполнив 'response_part.answer' в блоке итератора .each. Если вы этого не понимаете, мне нужно знать, что вы используете в своих представлениях: HAML или ERB? Тогда я покажу вам пример – MrYoshiji

0

Try:

Question.where(qtype: 'mobile').collect(&:response_parts) 

Это даст вам все в response_parts для всех questions с qtype = 'mobile'

Update: (Избежание N + 1 запросов)

Question.where(qtype: 'mobile').collect(&:response_parts) 

Это будет выполнить запрос выбора на каждый response_parts для каждого question, приводящей к запросам «N + 1».

Для того, чтобы избежать «N + 1 запросов», то есть один возвращающий вопрос и n запросы для извлечения resposne_parts, вы можете добавить includes(:join_relation) (где :join_relation является response_parts в вашем случае) следующим образом:

Question.includes(:response_parts).where(qtype: 'mobile').collect(&:response_parts) 
+0

Это не оптимизирован, если есть X Вопрос, где 'qtype ==«mobile'', он будет генерировать X SQL-запросов для их получения. (Знаменитые запросы N + 1: http://stackoverflow.com/questions/5452340/preventing-n1-queries-in-rails) – MrYoshiji

+0

Спасибо @MrYoshiji, я обновил свой ответ, чтобы обратиться к запросам «N + 1» вопрос. – vee

0

попробуйте это

Question.where(qtype: "mobile").first.response_parts 
+0

Это не заполняет требования: он получает только ответы на вопросы первого вопроса, а не все вопросы. – MrYoshiji

+0

@MrYoshiji ох я вижу.да, вы правы, я неправильно истолковал вопрос. Good Catch –

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