Skip to content

Instantly share code, notes, and snippets.

@juliocesar
Last active December 18, 2015 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juliocesar/5790235 to your computer and use it in GitHub Desktop.
Save juliocesar/5790235 to your computer and use it in GitHub Desktop.
ActiveRecord question

AR association with special attributes

Is there a straightforward way to have an intermediate model in AR (has many through type of scenario) which adds attributes to the association?

E.g.: has_many :fruits, :through => :qualified_fruits, :class_name => 'Fruit'.

Fruit objects returned have a "quality" attribute which actually lives in :qualified_fruits.

@jakcharlton
Copy link

Yep - just have a through model that has other attributes ... accept nested on parent to populate through model

@mipearson
Copy link

Not automatically, and my experience with AR tells me that trying to trick it into doing it automatically will just cause you pain.

The closest I can think of is this pattern:

has_many :fruits, class_name: QualifiedFruit

class QualifiedFruit < ActiveRecord::Base
  belongs_to :fruit

  delegate :taste, :colour, :ripeness, to: :fruit
end

@jakcharlton
Copy link

something like:

class MachineMembership < ActiveRecord::Base
  belongs_to :machine
  belongs_to :user

  as_enum :role, user: 0, admin: 1, owner: 3
end

class Machine < ActiveRecord::Base
  has_many :machine_memberships, dependent: :destroy
end

class User < ActiveRecord::Base
  has_many :machine_memberships, dependent: :destroy
end

@machine = Machine.new(machine_params)
@machine.machine_memberships.build({role: :owner, user: current_user})
if @machine.save

@jakcharlton
Copy link

The migration for join table :

class CreateMachineMemberships < ActiveRecord::Migration
  def change
    create_table :machine_memberships do |t|
      t.integer :role_cd, null: false
      t.belongs_to :machine
      t.belongs_to :user

      t.timestamps
    end

    add_index :machine_memberships, [:machine_id, :user_id], unique: true, name: 'index_machine_memberships_unique'
  end
end

@jakcharlton
Copy link

Quick copy/paste left off one line lol

class Machine < ActiveRecord::Base
  has_many :machine_memberships, dependent: :destroy
  has_many :users, through: :machine_memberships
end

That gives you

machine.users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment