Автоматический способ выбора всех столбцов объединенной таблицы в ActiveRecord?

Интересуюсь обновлением до Arel, если ActiveRecord еще поддерживает автоматический способ выбора столбцов из объединенных таблиц без необходимости явно перечислять их в предложении select.

Учитывая, что я присоединяю таблицу users к таблице posts, хотелось бы иметь возможность сделать что-то подобное более лаконичным образом:

  scope :select_user,
    select("posts.*, " + User.columns.map{|c| 
      "users.#{c.name} user_#{c.name}"}.join(','))

Итак, я хочу автоматически выбирать поля от пользователя, чтобы я мог сказать

Post.joins(:user).select_user.first.user_name

person aceofspades    schedule 26.05.2011    source источник


Ответы (2)


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

Post.includes(:user).first.user.name

Это приведет к двум запросам, одному select * from users и одному select * from posts where posts.user_id in (id1, id2, id3...) (при условии post belongs_to user), которые могут быть ударом по производительности в конкретной ситуации, но могут быть оправданы с точки зрения синтаксиса. В некоторых случаях это может быть даже быстрее Rails:include vs.:joins.

Arel также будет разумно использовать join, если вы добавите в запрос оператор ограничения, например. Post.includes(:user).where('users.name = "Bo Bob"') выполнит один запрос с join, а также позволит вам использовать ассоциации с результирующим объектом Post.

person sguha    schedule 24.05.2012
comment
github.com/ntalbott/query_trace очень полезен при разработке, чтобы увидеть, какие SQL-запросы генерируются каждым рельсом. команда. - person sguha; 25.05.2012
comment
на самом деле мой вопрос заключается в том, как выбрать все поля сообщения и пользователя, которые присоединились, и некоторые из имен полей совпадают. post.name и user.name - person wizztjh; 25.05.2012

Если я правильно понимаю ваш вопрос, вы можете сделать это с помощью «объединений»:

class Post < ActiveRecord::Base
  belongs_to :user

  scope :select_user, joins(:user).where('users.name = "Mary"')
  ...
end

или с параметром:

class Post < ActiveRecord::Base
  belongs_to :user

  scope :select_user, lambda {|user_name|
    joins(:user).where('users.name = ?', user_name)
  }
  ...
end
person moritz    schedule 26.05.2011
comment
Спасибо за Ваш ответ. Я не показывал соединение - вопрос больше о том, как автоматически выбирать поля из объединенной таблицы. - person aceofspades; 27.05.2011