Очистка контроллеров для ускорения применения - PullRequest
3 голосов
/ 21 мая 2011

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

В настоящее время в моем application_controller у меня есть много таких вещей:

@status_al = Status.find_by_name("Alive")
@status_de = Status.find_by_name("Dead")
@status_sus = Status.find_by_name("Suspended")
@status_hid = Status.find_by_name("Hidden")
@status_arc = Status.find_by_name("Archived")
@balloon_active = Post.where(:user_id => current_user.id, :status_id => @status_al.id )
@balloon_dependent = Post.where(:user_id => current_user.id, :status_id => @status_de.id )
@balloon_upcoming = Post.where(:user_id => current_user.id, :status_id => @status_sus.id )
@balloon_deferred = Post.where(:user_id => current_user.id, :status_id => @status_hid.id )
@balloon_complete = Post.where(:user_id => current_user.id, :status_id => @status_arc.id )

.. Это действительно маленький кусочек, я, по крайней мере, удвоил это с аналогичными вызовами.Проблема в том, что мне нужны эти цифры в значительной степени на каждой странице, но я чувствую, что слишком много раз здесь пишу в БД.

Есть идеи для лучшей реализации?

Ответы [ 2 ]

3 голосов
/ 22 мая 2011

Области применения

Прежде всего, вы должны переместить многие из них в scopes, что позволит вам использовать их гораздо более гибкими способами, такими как цепочка запросов с использованием ActiveRecord. Смотри http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html.

Индексы

Во-вторых, если вы все равно выполняете все эти запросы, убедитесь, что index ваша база данных, например, быстро найдет Status по имени. Пример миграции для выполнения первого индекса:

add_index :status (or the name of your Status controller), :name

Session

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

Если эти данные являются критическими и / или они должны быть обновлены до второй, тогда избегайте этой опции.

Счетчик кэширования

Если вам нужно определенное количество записей на регулярной основе, рассмотрите возможность установки counter_cache. В основном в ваших моделях вы делаете следующее:

Parent.rb
has_many :children

Child.rb
belongs_to :parent, :counter_cache => true

Убедитесь, что в вашей таблице parent есть поле с именем child_count, и Rails обновит это поле для вас при создании / удалении каждого ребенка. Если вы используете counter_caching, вы не попадете в базу данных, чтобы получить счет.

Примечание: Использование counter_caching приведет к немного более длительному действию создания и уничтожения, но если вы часто используете эти значения, обычно стоит использовать counter_cache.

2 голосов
/ 22 мая 2011

Для этого вам нужен только 1 запрос к базе данных, что-то вроде:

@posts = Post.where(:user_id => current_user.id).includes(:status)

Затем используйте Enumerable # group_by для сбора сообщений в разные категории:

posts_by_status = @posts.group_by do {|post| post.status.name }

, который даст вам хэш:

{'Alive' => [...], 'Dead' => [...]}

и т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...