2015-01-03 4 views
1

Если предположить, что у этой ассоциацииВыберите несколько значений из связанных моделей рельсов

User have_many posts 
Post belongs_to user 

User Post 
---------------- 
id  id 
name title 
     user_id 

Как перечислить только после заголовка и имя с включает в себя/присоединяется?

(список сообщений [название - имя пользователя])

@posts = Post.includes(:user).select('........') 

не предлагают эту

@posts = Post.all.each {|p| p.user.username} 

__________________UP_____________________

Он работал для объединения 2 таблиц.

Что делать, если я хочу использовать его для более сложного примера?

проверить, что мой предыдущий вопрос optimize sql query rails

@ ответ Humza отчасти работал. это может быть что-то вроде этого

@posts = Post.joins(:user, :category).paginate(:page => params[:page]).order("created_at DESC") 

, но он не отображает сообщения, которые не имеют категории

Я также нужно отобразить Gravatar, но я думаю, что я могу просто использовать user.email в usr_email и используйте gravatar_for (post.usr_email), но для этого мне нужно настроить помощника gravatar.

posts_controller.rb

def index 
    @posts = Post.includes(:user).includes(:comments).paginate(:page => params[:page]).order("created_at DESC") 
end 

index.html.erb

<%= render @posts %> 

_post.html.erb

<%= gravatar_for post.user, size:20 %> 
<%= link_to "#{post.title}", post_path(post) %> 
<%= time_ago_in_words(post.created_at) %> 
<%= post.comments.count %> 
<%= post.category.name if post.category %> 

ответ

1
Post.joins(:user, :category) 

, но он не отображает сообщения, которые не имеют категории

Это потому, что joins использует INNER JOIN для объединения таблиц вместе. Если вы хотите все от Post, даже если конкретная запись не имеет своего аналога в другой таблице, вам нужно использовать LEFT JOIN. К сожалению ActiveRecord не имеют хороший способ ее получения, и вам нужно будет сделать это вручную:

Post.joins("LEFT OUTER JOIN categories ON categories.post_id = posts.id")... 

См A Visual Explanation of SQL Joins для получения дополнительной информации.

+0

Вы пинали меня в правильном направлении) Теперь у меня есть следующее: Post.joins (: user) .joins ("LEFT OUTER JOIN category ON categories.id = posts.category_id"). Select ("posts.id как id, posts .title AS title, posts.created_at AS created_at, categories.name как cat_n, users.email AS user_em "). paginate (: page => params [: page]). order (" created_at DESC "). – kirqe

1

Вы можете вызывать методы массива на области применения так:

Post.includes(:user).map { |p| [p.title, p.user.name] } 

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

Это не может полностью ответить на ваш вопрос, я думаю, вы можете ограничить результаты запроса к только необходимые поля и в этом случае, я думаю, вы можете добавить .select('title', 'users.name') к запросу. (Не доступно для тестирования на данный момент)

3

Посмотрите на pluck.

Post.joins(:user).pluck(:title, :name) 

Обратите внимание, что он работает в этом случае, потому что нет никакой двусмысленности относительно name колонки, вы можете указать таблицу явно (pluck(:title, "users.name")).

+0

Он работает, но я получил ошибку, когда рендеринг @posts .... не является объектом, совместимым с ActiveModel. Он должен реализовать: to_partial_path. Обновленный вопрос. – kirqe

+0

Да, 'pluck' всегда возвращает простой массив Ruby. –

1

includes используется в случае высокой загрузки. В этом случае вам нужно joins.

posts = Post.joins(:user).select("posts.title AS title, users.name AS username") 

Вы можете получить доступ к значениям, то следующим образом:

post = posts.first 
post.title # will give the title of the post 
post.username # will give the name of the user that this post belongs to 

Если вы можете pluck несколько столбцов, то следующий может быть более полезным для вас:

posts = Post.joins(:user).pluck("posts.title", "users.name") 

результатом будет 2D-массив, причем каждый элемент представляет собой массив формы [post_title, post_username]

+0

Это сработало для меня, но что, если у меня будет более сложная связь. Обновлен мой вопрос. Можете ли вы также предложить любые статьи о присоединениях. Благодаря! – kirqe