# ActsAsJoinable It extends the functionality of `has_and_belongs_to_many`, conventionalizing common use cases. ## Usage ### Install sudo gem install acts-as-joinable ### Add Relationships Say you have `Post` and `Asset` models. If each `has_many` of each other `through` some join model, you can write it as such: class Post < ActiveRecord::Base acts_as_joinable_on :assets, :layouts, :tags, :slugs end class Asset < ActiveRecord::Base acts_as_joinable end That is a replacement for the longer (and non-polymorphic): class Post < ActiveRecord::Base has_and_belongs_to_many :assets end class Asset < ActiveRecord::Base has_and_belongs_to_many :posts end ## Why Many-to-many relationships end up requiring the same features 99% of the time: 1. Join Table that keeps track of `context` - [ActsAsTaggableOn](http://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb) - ActsAsAuthorized - [Preferences](http://github.com/pluginaweek/preferences/blob/master/generators/preferences/templates/001_create_preferences.rb) - [FriendlyId](http://github.com/norman/friendly_id/blob/ca9821192c8c3c4e81a938603151645c7cbe1470/generators/friendly_id/templates/create_slugs.rb) It looks like this: create_table :relationships do |t| t.references :parent, :polymorphic => true t.references :child, :polymorphic => true t.string :context t.timestamps end ## Alternatives - [ActsAsRelationable](http://github.com/winton/acts_as_relationable) ## Examples If you would like to define accessors that scope the relationship based on the `context` attribute of the `Relationship` model, you can do this: class Post < ActiveRecord::Base acts_as_joinable_on :assets, :scopes => [:featured, :thumb] end @post = Post.new @post.featured_assets << Asset.first If you need more fine-grained control over each relationship scope, you can use a block: class Post < ActiveRecord::Base acts_as_joinable_on :assets do has_one :featured_image, where(:...) has_many :thumbnails end acts_as_joinable_on :tags end @post = Post.new @post.featured_image = Image.first @post.thumbnails = Image.all The goal of this is to make it so you never have to create migrations or new classes, or rewrite the same code over and over again. Instead, you can just define `scopes` for cherry-picking the habtm items you'd like.