Arel :: SelectManager как получить доступ к результату, включая прогнозы - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь получить доступ к результатам объединения, в котором столбцы обеих таблиц указаны как часть проекции.

У меня есть 2 модели (Rails 4.2.11; Arel 6.0.4; Ruby 2.5.3)

# Table name: users
#
#  id         :integer          not null, primary key
#  name       :string(255)
#  email      :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null

class User < ActiveRecord::Base
  has_many :photos
end

# Table name: photos
#
#  id            :integer          not null, primary key
#  name          :string(255)
#  created_by_id :integer
#  assigned_id   :integer
#  created_at    :datetime         not null
#  updated_at    :datetime         not null
#  user_id       :integer

class Photo < ActiveRecord::Base
  belongs_to :user
end
creators = User.arel_table.alias('creators')
updaters = User.arel_table.alias('updaters')
photos = Photo.arel_table

photos_with_credits = photos.
join(photos.join(creators, Arel::Nodes::OuterJoin).on(photos[:created_by_id].eq(creators[:id]))).
join(photos.join(updaters, Arel::Nodes::OuterJoin).on(photos[:assigned_id].eq(updaters[:id]))).
project(photos[:name], photos[:created_at], creators[:name].as('creator'), updaters[:name].as('editor'))
# generated SQL
SELECT photos.name, photos.created_at, creators.name AS creator, updaters.name AS editor 
FROM photos 
INNER JOIN (SELECT FROM photos LEFT OUTER JOIN users creators ON photos.created_by_id = creators.id) 
INNER JOIN (SELECT FROM photos LEFT OUTER JOIN users updaters ON photos.updated_by_id = updaters.id)

Как бы я хотел обработать результат

photos_with_credits.map{|x| "#{photo.name} - copyright #{photo.created_at.year} #{photo.creator}, edited by #{photo.editor}"}.join('; ')

Это может быть очень глупый вопрос, но ... у меня нетя смог найти способ использовать результат SelectManager для получения значимого результата, поскольку карта была исключена (и удалена) из класса SelectManager.

Буду признателен за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Упрощенный построитель запросов activerecord / arel

исправленный код

photos_with_credits = Photo.select([photos[:name], photos[:created_at], creators[:name].as('creator'), updaters[:name].as('editor')]).
joins(photos.outer_join(creators).on(photos[:created_by_id].eq(creators[:id])).join_sources).
joins(photos.outer_join(updaters).on(photos[:assigned_id].eq(updaters[:id])).join_sources)

photos_with_credits.map do |photo|
  puts "#{photo.name} - copyright #{photo.created_at.year} #{photo.creator}, edited by #{photo.editor}".light_blue
end
исправленный SQL (проще)
SELECT photos.name, photos.created_at, creators.name AS creator, updaters.name AS editor 
FROM photos 
    LEFT OUTER JOIN users creators ON photos.created_by_id = creators.id 
    LEFT OUTER JOIN users updaters ON photos.assigned_id = updaters.id
0 голосов
/ 04 марта 2019

Мы должны найти способ вызвать SelectManage и получить ActiveRelation результат, затем мы можем повторить его, используя map и т. Д.

Поэтому я хотел бы предложить:

Photo.join(photos_with_credits.join_sources).map do |photo|
  "#{photo.name} - copyright #{photo.created_at.year} #{photo.creator}, edited by #{photo.editor}"}.join('; ')
end
...