简体   繁体   中英

Rails has_and_belongs_to_many on Model.where… (only some Model instances)

Ok, this is a tricky one for me. After at least 5 hours of googling and exerimenting with various metaprogramming techniques I have run out of ideas.

I am trying to add a has_and_belongs_to_many association only to some instances of my User model. Here is the relevant part of the code:

In my User Model:

class User < ActiveRecord::Base
  ...
  after_initialize :setup_trainer

  def setup_trainer
    return true unless trainer?
    self.class.instance_eval {include TrainerMethods}
  end

  module TrainerMethods

    extend ActiveSupport::Concern

    included do
      has_and_belongs_to_many :trainings
    end

  end
  ...
end

And then in my Training Model:

class Training < ActiveRecord::Base
  has_and_belongs_to_many :trainers, class_name: "User"
end

This is only one of the several techniques I tried and the issue here is that not just trainers but every User is added the habtm association.

Is there a way I can add the habtm association only to trainers?

UPDATE: If I simply add the association to the User model as suggested. both regualar users and trainers that don't have trainings would return [] Do you think this is fine and in case we need to clarify what kind of user we are looking at we call the @user.trainer? method?

Thank you very very much.

ActiveRecord associations just mean you can (if required) create / build associative data. Associations are not a binding thing - you don't have to include data just because you have one set up


has_many :through

If you'd like to associate a number of trainers to users through a mediator model, you might be better doing this:

#app/models/user.rb
Class User < ActiveRecord::Base
    has_many :trainings, foreign_key: "trainer_id", association_foreign_key: "user_id"
    has_many :trainers, class_name: "User", through: :trainings, foreign_key: "trainer_id"
end

This will give you a schema like this:

users
id | user | details | created_at | updated_at

trainings
id | user_id | trainer_id | created_at | updated_at 

Both user_id & trainer_id will reference the User model

It will allow you to do this:

@user = User.find(id)
@trainers = @user.trainers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM