You use has_and_belongs_to_many only when you're setting a many-to-many association (in other words, when the other side also has has_and_belongs_to_many). That is the meaning of this association.
You should have
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, :through => :post_tags
end
class PostsTag < ActiveRecord::Base
belongs_to :tag
belongs_to :post
end
class Post < ActiveRecord::Base
has_many :posts_tags
has_many :tags, :through => :posts_tags
end
Notice that I used the plural, post_tags (because this is the correct way).
If you have the situation like in your comment, you should have a
belongs_to :post_tag
in your Post model, and
has_many :posts
in your PostTag model.
You may ask now: "Why should I use belongs_to :post_tag? It doesn't belong to a tag, it has a tag. So, shouldn't I use has_one :post_tag?". This was also my question at first, but then I figured that it Rails cannot always perfectly suit the english language. You need the post_tag_id column on your post, and belongs_to expects exactly that. On the other hand, has_one would expect that a column named post_id is present on the other side, that is in your post_tag. But this would be impossible, because post_tag has many posts (not only one), so the post IDs cannot be held in post_tags.
Update:
The difference between associations are only in the methods you are provided and options you can pass in (the one explained in the Rails guide on associations). For example, has_one and belongs_to have the same methods:
association(force_reload = false)
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
But, for example, methods association= and create_association imply different things concerning where the foreign key should be (like I explained above).
has_and_belongs_to_many and has_many probably don't have anything different in their methods, but they differ in the options you can pass. For example, you can pass in
:dependent => :destroy
on the has_many association, but you can't pass it to a has_and_belongs_to_many, because that wouldn't make sense, since it implies a many-to-many association; if a parent record is destroyed, child records can still be connected with other records, so they shouldn't also be destroyed.