Запрос активной записи Rails

#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