#ruby-on-rails #ruby #sqlite
#ruby-on-rails #ruby #sqlite
Вопрос:
Как бы я выполнил подобный запрос. у меня есть
@model = Model.near([latitude, longitude], 6.8)
Теперь я хочу отфильтровать другую модель, которая связана с приведенной выше.
(помогите мне найти правильный способ сделать это)
model2 = Model2.where("model_id == :one_of_the_models_filtered_above", {:one_of_the_models_filtered_above => only_from_the_models_filtered_above})
model.rb был бы таким
has_many :model2s
модель 2.rb
belongs_to :model
Прямо сейчас это выглядит так (после @model = Model.near([широта, долгота], 6.8)
model2s =[]
models.each do |model|
model.model2s.each do |model2|
model2.push(model2)
end
end
Я хочу выполнить то же самое, но вместо этого с помощью запроса активной записи
я думаю, что я что-то нашел, почему это не удается
Model2.where("model.distance_from([:latitude,:longitude]) < :dist", {:latitude => latitude, :longitude => longitude, :dist => 6.8})
этот запрос выдает эту ошибку
SQLite3::SQLException: near "(": syntax error: SELECT "tags".* FROM "tags" WHERE (model.distance_from([43.45101666666667,-80.49773333333333]) < 6.8)
почему
Комментарии:
1. для начального бита вы можете использовать предложение «IN» ? так нравится
Model2.where("model_id in ?", @models)
. Во второй части вы пытаетесь передать массив в distance_from? Можете ли вы иметь атрибут в модели, содержащий значение, которое можно было бы использовать в запросе вместо вызова метода distance_from?2. Вам нужно будет реализовать свой
distance_from
вариант SQL в SQLite или добавить пользовательскую функцию для его реализации.3. Вы могли бы использовать
join
для выбора всех объектов Model2, которые имеют совпадение в запросе по модели
Ответ №1:
используйте includes
. Он будет загружать связанные модели (только два SQL-запроса вместо N 1).
@models = Model.near( [latitude, longitude], 6.8 ).includes( :model2s )
поэтому, когда вы это сделаете @models.first.model2s
, связанные model2s уже будут загружены (см. Руководства по RoR для получения дополнительной информации).
Если вы хотите получить массив всех model2s, принадлежащих вашей коллекции моделей, вы можете сделать :
@models.collect( amp;:model2s )
# add .flatten at the end of the chain if you want a one level deep array
# add .uniq at the end of the chain if you don't want duplicates
collect
(также называемый map
) соберет в массив результат любого блока, переданного каждому из вызывающих элементов (это делает то же самое, что и ваш код, см. Документ Enumerable для получения дополнительной информации). amp;
Перед символом преобразует его в Proc
, передаваемый каждому элементу коллекции, так что это то же самое, что и запись
@models.collect {|model| model.model2s }
еще одна вещь: @mu прав, кажется, SQLite не знает о вашей distance_from
хранимой процедуре. Поскольку я подозреваю, что это вопрос, связанный с ГИС, вы можете спросить об этой конкретной проблеме наgis.stackexchange.com