Подтвердить что ты не робот

Rails ActiveRecord: динамическое построение запросов

Я пытаюсь собрать ряд классов, которые могут использовать ActiveRecord для динамического создания и выполнения сложных запросов. Я чувствую себя очень комфортно со всей практикой:

MyModel.select("id, name, floober").join(:creator).where(:is_active => true)

То, с чем я борюсь, использует эти вещи для создания запроса без возможности определить, сколько будет каждого возможного метода (количество объединений, число или где клаузулы, лимит, группа и т.д.), досрочно. У меня может быть 2 соединения, или нет объединений в зависимости от того, откуда он звонил.

В связи с тем, как я получаю эти вещи - список объединений, список столбцов, список предложений и т.д., я могу слепо соединить их вместе. Я должен объединить столбцы вместе, упорядочить соединения, связать предложения where, чтобы я не мог перебирать различные списки.

Я пытаюсь избежать записи какого-либо необработанного SQL.

Одна вещь, которую я пробовал, заключалась в том, чтобы создать рубиновое выражение как строку, а затем уклониться от нее в конце, и когда я закончил, я почувствовал себя грязным, как будто мне нужна ванна. Я ищу способ кэшировать состояние моего запроса до тех пор, пока все части не будут накоплены, а затем выполните их.

Я бродил "с рельсов"?

спасибо заранее...

4b9b3361

Ответ 1

Думаю, я понял это. Я был довольно уверен в моем понимании методов AR-запросов. Оказывается, ActiveRecord фактически не выполняет запрос, пока вы не попытаетесь использовать результаты. В результате можно делать такие вещи, как:

model_query = MyModel.select("column12, column32")
model_query = model_query.joins(:user)
model_query = model_query.where(:column12 => true)

то после того, как все будет создано, вы можете сделать

model_query.each do |record|
  ...
end

Запрос фактически не выполняется до тех пор, пока вы не вызовете каждый (или какой-либо метод, который вы используете, который требует результатов запроса).

Я получил это, посмотрев Railscasts 202 и 215. Я люблю Райана Бейтса.

Ответ 2

В этом случае send может быть вашим другом. Это по-прежнему довольно произвольное выполнение кода, но по крайней мере вы не используете eval. Не совсем ясно, есть ли у вас эти части запроса сразу или со временем их наращивают. Если они присутствуют в одном цикле запросов/ответа HTTP, то повторение через части запроса и выполнение send, в зависимости от ситуации, имеет смысл.

OTOH, если вы получаете его через Ajax или какие-то другие средства, где условия являются кумулятивными, вам, возможно, придется искать либо кэширование существующих частей, либо еще более экзотическое решение.