Во-первых - у вас, похоже, неправильные ассоциации. Теги и сообщения являются ассоциацией «многие ко многим», а не «один ко многим».
Я настоятельно рекомендую взглянуть на одну из реализаций acts_as_taggable , чтобы сделать это для вас. В противном случае вы можете создать has_many :through
ассоциацию, если хотите, но это будет заново изобретать колесо.
Вызов count()
для коллекции для каждой загрузки страницы - очень плохая идея 1010 *, потому что это заставит вас попасть в базу данных для каждого тега; очень дорогая операция в масштабе. Кроме того, количество постов с данным тегом не является цифрой, которую нужно вычислять во время запроса, поэтому такой подход является дорогостоящим и ненужным.
Rails имеет встроенную функцию под названием counter_cache
, которая позаботится об этом за вас, кэшируя количество связанных записей в целочисленном поле и обновляя его при создании новых записей. Вот как вы это настроили:
Создание миграции для таблицы tags
:
def up
add_column :tags, :taggings_count, :integer, :default => 0
Tag.reset_column_information
Tag.all.each do |t|
Tag.update_counters t.id, :taggings_count => t.taggings.length
end
end
def down
remove_column :tags, :taggings_count
end
И изменить belongs_to
ассоциацию:
class Tagging < ActionRecord::Base
belongs_to :tag, :counter_cache => true
belongs_to :post
end
Если вы создаете свою собственную систему тегирования, вы подключите оставшиеся две модели примерно так:
class Post < ActiveRecord::Base
has_many :taggings
has_many :tags, :through => :taggings
end
class Tag < ActiveRecord::Base
has_many :taggings
has_many :posts, :through => :taggings
end
Но, опять же, было бы намного проще использовать готовое решение.
С этого момента каждый раз, когда вы создаете новую Post
ассоциацию для Tag
с помощью модели Tagging
, он автоматически обновляет для вас столбец taggings_count
.
В ваших представлениях вы можете отображать счетчик при выполнении итерации, как и любой другой столбец:
<%= link_to "#{tag.name} (#{tag.taggings_count})", posts_path(:tag_name => tag.name) %>
Дальнейшее чтение:
ActiveRecord has_many: через ассоциации
Основы ассоциации ActiveRecord (: counter_cache обсуждается в разделе 4.1.2.4)