Rails: правильный способ превратить отношение activerecord к массиву?
Я пытался выбрать объекты uniq по одному атрибуту, используя @videos.uniq{|p| p.author}
time = Time.new(2014, 12)
start_time = time.beginning_of_month
end_time = time.end_of_month
videos = Video.where("created_at > ? AND created_at < ?", start_time, end_time).where("likes > ?", 15)
selected_videos = videos.uniq{|p| p.author}
puts videos.count, videos.class, selected_videos.count
#=> 23, Video::ActiveRecord_Relation, 23
videos_first = videos.first(23)
selected_videos = videos_first.uniq{|p| p.author}
puts videos_first.count, videos_first.class, selected_videos.count
#=> 23, array, 10
.uniq
не для ActiveRecord_Relation
. И проблема в том, что запрос возвращает Video::ActiveRecord_Relation
, но мне нужно array
.
Конечно, это может быть достигнуто с помощью to_a
, но является ли это элегантным?
- Каков правильный способ решения этой проблемы?
- Можно ли использовать
.uniq
для activerecord:relation
?
Ответы
Ответ 1
Если вам нужен доступ к результату запроса, просто используйте #to_a
в экземпляре ActiveRecord:: Relation.
В направляющих rails вы можете найти заметные изменения в Rails 4.0: "Model.all теперь возвращает ActiveRecord:: Relation, а не массив записей. Используйте Relation # to_a, если вам действительно нужен массив. В некоторых конкретных случаях это может привести к поломке при обновлении". Это справедливо для других методов отношений, таких как: where.
selected_videos = videos.to_a.uniq{|p| p.author}
Ответ 2
.uniq
не имеет большого смысла, когда он применяется к полной записи активной записи.
Учитывая, что по крайней мере один или несколько из трех атрибутов - id
, created_at
и updated_at
- различны для каждой строки, применяя videos.uniq{|p| p.author}
, где videos
является ActiveRecord::Relation
, включая все поля, вернет все строки в ActiveRecord::Relation
.
Когда объект ActiveRecord::Relation
имеет подмножество значений, uniq
сможет определить различные значения из них.
Например: videos.select(:author).uniq.count
даст 10 в вашем примере.
Разница между ActiveRecord::Relation#uniq
и Array#uniq
заключается в том, что версия Array принимает блок и использует возвращаемое значение блока для сравнения. Версия ActiveRecord:: Relation uniq просто игнорирует блок.