Search code examples
ruby-on-railsrubyrails-activerecordmodelsmodel-associations

How to obtain different type of collections for the same Model in an Association in Rails 4?


In my application I have a User model and a Job model. Users can post many jobs, and other users can apply to these jobs by posting proposals. The job poster can then select a user from the list of users who have applied, later this user will be assigned to work on this job.

This means that the Job model should have two kinds of foreign keys for User, maybe something like poster_id and worker_id.

Currently my models look like this:

class Job < ActiveRecord::Base
   belongs_to :user
   has_many :proposals, dependent: :destroy
end

class User < ActiveRecord::Base
   has_many :jobs, dependent: :destroy
   has_many :proposals, through: :jobs
end

class Proposal < ActiveRecord::Base
    belongs_to :job
    belongs_to :user
end

My question is, what are the correct associations between these models in order to work the way I described?

For example, I need to access the posted jobs of a certain user, as well as the jobs this user is subscribed to (worker_id). These are different collections, but of the same model Job...

Something like:

@user.posted_jobs.all
@user.current_jobs.all

These would return different Jobs for the same @user.

Would really appreciate help.


Solution

  • Assuming your Job can only have one worker that is set when a Proposal is accepted, you'd want something like this:

    class Job < ActiveRecord::Base
       belongs_to :poster, class_name: 'User', foreign_key: 'poster_id'
       belongs_to :worker, class_name: 'User', foreign_key: 'worker_id'
       has_many :proposals, dependent: :destroy
    end
    
    class User < ActiveRecord::Base
       has_many :posted_jobs, class_name: 'Job', foreign_key: 'poster_id', dependent: :destroy
       has_many :current_jobs, class_name: 'Job', foreign_key: 'worker_id'
       has_many :proposals, through: :jobs
    end
    
    class Proposal < ActiveRecord::Base
        belongs_to :job
        belongs_to :user
    end
    

    With this approach, you can get user.posted_jobs and user.current_jobs.

    See this: Same Model for Two belongs_to Associations