Mateusz Urbański
Mateusz Urbański

Reputation: 7862

Using similar scopes in ActiveRecord

I have a problem with using similar scopes in ActiveRecord. I have 3 models:

Person:

class Person < ActiveRecord::Base
  has_many :survey_packs

  def self.by_first_name(text)
    where(first_name: text)
  end
end

SurveyPack:

class SurveyPack < ActiveRecord::Base
  has_many :survey_instances, inverse_of: :survey_pack
  belongs_to :person
end

and SurveyInstance:

class SurveyInstance < ActiveRecord::Base
  belongs_to :survey_pack, inverse_of: :survey_instances
  belongs_to :student, class_name: 'Person', foreign_key: :person_id

  scope :teacher_full_name, ->(text) { SurveyInstance.joins(:person).merge(Person.by_first_name(text)) }
  scope :student_full_name, ->(text) { SurveyInstance.joins(:student).merge(Person.by_first_name(text)) }
end

The problem is that I cant join this scopes together:

  scope :teacher_full_name, ->(text) { SurveyInstance.joins(:person).merge(Person.by_first_name(text)) }
  scope :student_full_name, ->(text) { SurveyInstance.joins(:student).merge(Person.by_first_name(text)) }

For example I have a survey_instance that student name is: 'Student' and Teacher name is: 'Teacher':

SurveyInstance.teacher_full_name('Teacher') #this will work
SurveyInstance.student_full_name('Student') #this will also work
SurveyInstance.teacher_full_name('Teacher').student_full_name('Student') #this will not work...

I have no idea how to solve this problem...

Upvotes: 0

Views: 40

Answers (1)

nayiaw
nayiaw

Reputation: 1456

Not sure whether this works or not, but the logic is similar to this:

class SurveyInstance < ActiveRecord::Base
  belongs_to :survey_pack, inverse_of: :survey_instances
  belongs_to :student, class_name: 'Person', foreign_key: :person_id

  scope :full_name, ->(type, text) { SurveyInstance.joins(type).merge(Person.by_first_name(text)) }
end

Extract the association out so that the symbol is passed through the scope call.

To call the scope:

SurveyInstance.full_name(:person, 'Teacher')
SurveyInstance.full_name(:student, 'Student')

Upvotes: 1

Related Questions