1
votes

I'm trying to create an app for users to create a list of watches they own or wish to buy. I want users to be able to describe a lot of detail/attributes about their watches. I'm trying to create a parent/child association, but not using STI, as the children models have different data and I don't want a bunch of null values in my table.

I have 4 tables:

  • users
    • Some user attributes
  • watches
    • user_id
    • A bunch of attributes that are common to all watches, name, brand etc.
    • content_id
    • content_type
  • mechanical_watches
    • Some attributes that only apply to mechanical watches
  • quartz_watches
    • some attributes that only apply to quartz watches

Models

class User < ApplicationRecord
 include Clearance::User

 has_many :watches
end

class Watch < ApplicationRecord
 belongs_to :user
 belongs_to :content, polymorphic: true
end

class MechanicalWatch < Watch
 has_one :watch, as: :content
end

class QuartzWatch < Watch
 has_one :watch, as: :content
end

I'm not a 100% sure if I've setup the associations correctly. But the problem I'm having is that when I enter MechanicalWatch into the console it returns only the attributes on Watch not any of the attributes in the mechanical_watches table. I've tried everything I can think of. Any thoughts as to what I'm doing wrong.

I'm using Rails 5, Ruby 2.3.1, and Postgres for the db.

2

2 Answers

0
votes

I don't think you want inheritance on MechanicalWatch or QuartzWatch. They appear to be separate tables from Watch. The relationship you show is MechanicalWatch "has a" Watch, instead of MechanicalWatch "is a" Watch.

You would change

class MechanicalWatch < Watch

to

class MechanicalWatch

0
votes

From what I understand you want to be able to create a mechanical_watch instance, but still have the ability to set the fields on the watch model.

I.e. MechanicalWatch.new.field_on_watch = 4

If that's correct then u can look at this:

http://api.rubyonrails.org/classes/Module.html

The pattern your looking for is delegation.

An important question to ask though: do you plan to use watches in a polymorphic way. I.e. Will u show all types of watches on the same page? Or will different watches be displayed separately?