Согласно the pastebin предоставленной О.П., следующее утверждение:
Entry.joins(:math_test_before, :math_test_after)
.where('math_test_before.score > math_test_after.score').all
произвел следующий SQL-запрос:
Entry Load (0.3ms) SELECT "entries".* FROM "entries" INNER JOIN "math_tests" ON "math_tests"."entry_id" = "entries"."id" INNER JOIN "math_tests" "math_test_afters_entries" ON "math_test_afters_entries"."entry_id" = "entries"."id" WHERE (math_test_before.score > math_test_after.score)
Дать правильное утверждение теперь тривиально. Вот он:
Entry.joins(:math_test_before, :math_test_after)
.where('math_tests.score > math_test_afters_entries.score').all
Однако при запуске этого запроса вы не получите желаемых результатов. Это связано с тем, что ваши ассоциации не были настроены должным образом. Посмотрите на свои журналы: таблица math_tests соединяется с таблицей записей с одним и тем же внешним ключом дважды, что означает, что тот же тест будет действовать как перед, так и после теста.
Вам необходимо внести некоторые изменения в настройку вашей ассоциации. Прежде всего, ваша запись должна belong_to
в два MathTest экземпляры, как это:
class Entry < ActiveRecord::Base
belongs_to :math_test_before, :class_name => 'MathTest'
belongs_to :math_test_after, :class_name => 'MathTest'
end
Вам также необходимо добавить столбцы с именем math_test_before_id
и math_test_after_id
таблицу записей путем создания соответствующей миграции и запуска rake db:migrate
. После этого отредактируйте ваш класс MathTest следующим образом:
class MathTest < ActiveRecord::Base
has_one :before_entry, :class_name => 'Entry', :foreign_key => 'math_test_before_id'
has_one :after_entry, :class_name => 'Entry', :foreign_key => 'math_test_after_id'
end
Предоставленный запрос должен работать тогда.
ПОЖИЛЫХ ПОПЫТКИ: Первая и вторая попытка, описанная ниже, чтобы написать этот запрос не удались. Они сохраняются здесь для записи, чтобы другие не тратили время на это.
Что-то, как это должно работать:
Entry.joins(:math_test_before, :math_test_after)
.where('math_test_before.score > math_test_after.score').all
Просьба представить выход выше заявление, даже если он не даст вам желаемый результат. Я опасаюсь только потому, что мне никогда не приходилось использовать атрибут class_name ассоциации has_one.
ОБНОВЛЕНИЕ Посмотрите на этот ответ: https://stackoverflow.com/a/8588520/563535. Согласно плакату, сгенерированное псевдоним - <assoc_name>_<entity_name_plural>
. Таким образом, ваш запрос должен, вероятно, использовать math_test_before_entries.score > math_test_after_entries.score
. Получение взгляда на сгенерированный оператор поможет нам уловить это дальше.
Вы можете присоединяться к предложениям() или предпочитаете писать необработанный sql? – Chandranshu