In migrations, you can also edit your models. I have a Topic and a Post. A topic has many posts. The models are already created using previous migrations. Now I want to add 3 new fields to Topic—posts_count, replied_by, and replied_at.
Here is the migration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class AddCachedFieldsOnTopic < ActiveRecord::Migration class Topic < ActiveRecord::Base has_many :posts, :order => "posts.created_at" end class Post < ActiveRecord::Base; end def self.up add_column :topics, :posts_count, :integer, :default => 0 add_column :topics, :replied_by, :integer add_column :topics, :replied_at, :datetime Topic.find(:all, :include => :posts).each do |topic| last_post = topic.posts.last posts_count = topic.posts.size Topic.update_all(["posts_count = ?, replied_by = ?, replied_at = ?", posts_count, last_post.user_id, last_post.created_at], ["id = ?", topic.id]) if last_post end end def self.down remove_column :topics, :posts_count remove_column :topics, :replied_by remove_column :topics, :replied_at end end |
- posts_count will be used by rails for caching. In the post model, I’ll put :belongs_to :topic, :counter_cache => true. Set the default to 0.
- You can actually get these fields through the association—topic.posts.count, topic.posts.last.user, topic.posts.last.created_at – but I’m adding it to Topic to avoid the additional queries.
- I’m looking at (copying) the beast application.
