2012-02-25 3 views
0

Если у меня есть метод, модель, как:модели или переменная экземпляра контроллера, Ruby по рельсам 3

def favoured_users 
self.followers.limit(5).order("created_at") 
end 

с видом блока, как:

<% 5.times do |i| %> 
    <li><%= @user.favoured_users[i].name %></li> 
<% end %> 

... бы я называя favoured_user пять раз и каждый раз, когда вы спрашиваете у 5 пользователей, заканчивая тем, что вызывается как 25 пользователей?

Я просто интересно, если я должен положить результат favoured_users в переменной в мой контроллер вместо:

@favoured_users = @user.followers.limit(5).order("created_at") 

бы, что будет меньше вызовов на сервер?

** EDIT **

Я не уверен, если это означает, что значение приходит из кэша, оказывается, что (bcos кэша, но я не знаю, вот что это значит), но Я явно не рассказали об этом, я должен сделать все, чтобы убедиться, что он пришел сюда кэш:

User Load (0.6ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`followed_id` WHERE `relationships`.`follower_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`followed_id` WHERE `relationships`.`follower_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`followed_id` WHERE `relationships`.`follower_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`followed_id` WHERE `relationships`.`follower_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT COUNT(*) FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`follower_id` WHERE `relationships`.`followed_id` = 1 
User Load (0.5ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`follower_id` WHERE `relationships`.`followed_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`follower_id` WHERE `relationships`.`followed_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`follower_id` WHERE `relationships`.`followed_id` = 1 ORDER BY full_name, created_at LIMIT 5 
CACHE (0.0ms) SELECT `users`.* FROM `users` INNER JOIN `relationships` ON `users`.`id` = `relationships`.`follower_id` WHERE `relationships`.`followed_id` = 1 ORDER BY full_name, created_at LIMIT 5 

ли значение возвращающегося из кэша?

EDIT Я не уверен, как получить доступ к переменному с моей точкой зрения, у меня есть метод, как на редактирование СЦББИ и на моем взгляде, я пытаюсь:

<% @user.favoured_followers do %> 

    <li><%= @favoured.first.username unless @favoured.first.blank? %></li> 
    <li><%= @favoured.second.username unless @favoured.second.blank? %></li> 
    <li><%= @favoured.third.username unless @favoured.third.blank? %></li> 
    <li><%= @favoured.fourth.username unless @favoured.fourth.blank? %></li> 
    <li><%= @favoured.fifth.username unless @favoured.fifth.blank? %></li> 

<% end %> 

Ничего возвращаются?

+0

Rails делает попытку кэшировать избыточные запросы в запрос. Эти сообщения 'CACHE' означают, что он возвращает значение из кеша, а не снова удаляет базу данных. Это полезно, но вам лучше явно кэшировать значения, как в ответе Себи, чем в зависимости от Rails, чтобы сделать это за вас. – Brandan

+0

Я понимаю, теперь Брэндон благодарит. – Darcbar

ответ

3

Если вы посмотрите в своем журнале, вы сможете проверить, попадает ли он в кеш или нет для каждого вызова функции. Это не похоже на попадание в кеш, поэтому запрос на загрузку последователей будет повторяться 5 раз для каждого пользователя. i.e для каждого @user вы будете запускать запрос 5 раз. Так что кеширование значения в переменной, безусловно, является лучшей идеей.

Edit: Вы можете изменить метод модели, как это:

def favoured_users 
    @favoured ||= self.followers.limit(5).order("created_at") 
end 

@favoured переменным будет создан в первый раз это называется, а затем в течение последующих вызовов он будет возвращен без запрос уволен.

Ваш код просмотра должен быть одинаков без каких-либо изменений. то есть:

<% 5.times do |i| %> 
    <li><%= @user.favoured_users[i].name %></li> 
<% end %>  
+0

Я бы предпочел использовать метод в модели, как бы я мог кэшировать значение из модели? ... или мне нужно было бы вызвать метод модели с контроллера для установки переменной? – Darcbar

+0

Лучше, если вы зацикливаете этот путь <% @ user.favoured_users.each do | user | %>

  • <% = user.name%>
  • <% end %> – DeathHammer

    +0

    Причина, по которой я зацикливаюсь, так это то, что я хочу, чтобы теги 5 li отображались даже при возвращении только трех пользователей. – Darcbar

    0

    Если я должен делать .. я сделаю ниже способа

    Внутри контроллер

    @favoured_users = @user.followers.limit(5).order(:created_at) 
    

    вида изнутри

    <% @favoured_users do |user| %> 
        <li><%= user.name %></li> 
    <% end %> 
    <% (5 - @favoured_users.count).times do%> 
    <li>&nbsp;</li> 
    <% end %> 
    
    +0

    Это не сработает, как я хочу, чтобы он работал ... Мне нужны теги 5 li для рендеринга, даже если переменная содержит только 3 пользователя. – Darcbar

    +0

    отредактировал ответ, чтобы показать 5 тегов все время –

    Смежные вопросы