Условия рендеринга @users (исключая current_users и пользователей с дружеской ассоциацией)

В настоящее время я делаю условия в представлении. Мне нужно сделать это в модели или контроллере, но я не нашел работающего способа.

У меня есть представление, отображающее 10 пользователей через частичное, которое сортирует их по количеству друзей (все примеры упрощены):

Index.html.erb

<%= render @users %>

_partial.html.erb

<% unless current_user == user or current_user.friending?(user) %>
  <%= user.name %>
<% end %>

модели/user.rb

scope :top, :order => "friends_count DESC"

users_controller.rb/index

@users = User.top.limit(10)

Но в моем случае он проверяет валидацию в партиале для каждого пользователя. Как я могу сделать это более эффективно в области действия или контроллере и проверить на всех?

Большое спасибо за все ответы. Очень ценится.


person Kasperi    schedule 22.11.2013    source источник
comment
Я не знаю, поможет ли это в ваших условиях, но почему бы не использовать гем will_paginate?   -  person Tamer Shlash    schedule 23.11.2013


Ответы (2)


class User
  scope :top, order("friends_count DESC")
  scope :skip_user, lambda{|user| where("id != ?", user.id) }
  scope :skip_user_friends, lambda{|user| where("friend_id != ?", user.id }
end

users_controller.rb

@users = User.top.skip_user(current_user).skip_user_friends(current_user).limit(10)
person AndyV    schedule 22.11.2013
comment
Хорошая работа! В этом есть еще один плюс. Так как общие запросы распределены по цепочке, будет выполняться только один оптимизированный SQL-запрос по таблице при извлечении @users. - person kiddorails; 23.11.2013
comment
Да, это была цель. Мне нравится разбивать области видимости на более мелкие фрагменты, потому что их легче повторно использовать в других контекстах. - person AndyV; 23.11.2013

Когда вы получите @users в контроллере, вы можете использовать #select.

@users = User.top.reject { |user| current_user == user or current_user.friending?(user) }.limit(10)
person kddeisz    schedule 22.11.2013
comment
Он использует unless в своем представлении; таким образом, отклоняя те users, которые соответствуют заданным условиям. Я думаю, для этого вам следует использовать reject вместо select. - person kiddorails; 23.11.2013
comment
или просто отмените условия: User.top.select { |user| текущий_пользователь != пользователь || !current_user.friendling?(пользователь) }.limit(10) - person bjhaid; 23.11.2013
comment
@bjhaid технически, да. Но это только сделает общее утверждение немного неясным для третьего лица =› !ruby_convention. :) - person kiddorails; 23.11.2013
comment
Обновлено, чтобы быть отклоненным. - person kddeisz; 25.11.2013