0

I've seen some posts dealing with this, and am trying to determine the best solution.

Semantically, I want a Client model with a one-to-one relationship with a Survey. There are different kinds of surveys that have different fields but I want to share a significant amount of code between them. Because of the different fields I want different database tables for the surveys. There is no need to search across different types of surveys. It feels like I want the foreign key in the Client table for fast retrieval and potential eager-loading of the Survey.

So theoretically I think I want polymorphic has_one and multiple inheritance something like this:

class Client < ActiveRecord::Base
  has_one :survey, :polymorphic => true
end

class Survey
  # base class of shared code, does not correspond to a db table
  def utility_method
  end
end

class Type1Survey < ActiveRecord::Base, Survey
  belongs_to :client, :as => :survey
end

class Type2Survey < ActiveRecord::Base, Survey
  belongs_to :client, :as => :survey
end

# create new entry in type1_surveys table, set survey_id in client table
@client.survey = Type1Survey.create()

@client.survey.nil?            # did client fill out a survey?
@client.survey.utility_method  # access method of base class Survey
@client.survey.type1field      # access a field unique to Type1Survey

@client2.survey = Type2Survey.create()
@client2.survey.type2field     # access a field unique to Type2Survey
@client2.survey.utility_method

Now, I know Ruby does not support multiple inheritance, nor does :has_one support :polymorphic. So is there a clean Ruby way to achieve what I'm getting at? I feel like it's right there almost...

user206481
  • 248
  • 5
  • 13

1 Answers1

0

Here's how I would do this:

class Client < ActiveRecord::Base
  belongs_to :survey, :polymorphic => true
end

module Survey
  def self.included(base)
    base.has_one :client, :as => :survey
  end

  def utility_method
     self.do_some_stuff
  end
end

Type1Survey < ActiveRecord::Base
  include Survey

  def method_only_applicable_to_this_type
    # do stuff
  end
end

Type2Survey < ActiveRecord::Base
  include Survey
end
MrTheWalrus
  • 9,670
  • 2
  • 42
  • 66
  • Aha! I will try this, I was stuck on the semantics of a client "belonging" to a survey vs. the other way around, but I see now this puts the foreign key where I want it. I will turn my base class into a module also and report back... – user206481 Oct 18 '12 at 15:28
  • @user206481 How did it go? – Matthew Moisen Jul 27 '13 at 05:19