0

In a rails application, I have a base model like this :

class User < ActiveRecord::Base
  attr_accessible :email, :name
end

And an inheritance from this model, like this :

class Provider < User
  belongs_to :user

  attr_accessible :business_name, :contact_name, :business_phone_number,
    :business_email, :website, :user_id
end

When I do :

Provider.new.user_id

It say NoMethodError: undefined method 'user_id' for #<Provider:0x007f63ec8b3790>.

When I just do Provider.new I have this:

#<Provider id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, type: "Provider">

This is a part of my schema.rb :

  create_table "providers", :force => true do |t|
    t.string  "business_name",         :null => false
    t.string  "contact_name",          :null => false
    t.string  "business_phone_number", :null => false
    t.string  "business_email",        :null => false
    t.string  "website"
    t.integer "user_id"
  end

  create_table "users", :force => true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at",                             :null => false
    t.datetime "updated_at",                             :null => false
  end

As you can see, the attributes accessibles for Provider are not accessible. Do you have a solution?

Thanks!

Dougui
  • 7,142
  • 7
  • 52
  • 87

2 Answers2

2

As discussed in the answer to Single Table Inheritance to refer to a child class with its own fields, ActiveRecord's implementation of Single Table Inheritance does not involve additional tables. All subclasses share the same table and rely on a type field to identify subclasses. That explains why your Provider instances only contain the fields available in your users table, including the type field that Rails adds for the subclassing support. Your providers table is unused.

Community
  • 1
  • 1
Peter Alfvin
  • 28,599
  • 8
  • 68
  • 106
0

The same table is used at the database level. STI is achieved by adding a new column to the existing table. The new column usually named 'type' is used to hold the information whether it is a 'Provider' or 'User'

Here is how the the model queries translate to a sql query

When the User model is queried, as per your example, it searches 'users' table and includes all available type values in the condition

> User.first
SELECT  `users`.* FROM `users`  WHERE `users`.`type` IN ('User', 'Provider')  ORDER BY `users`.`id` ASC LIMIT 1

When the Provider model is queried, type is set as 'Provider' in the condition and so the results get filtered. The underlying database table remains the same ie 'users'

 > Provider.first
SELECT  `users`.* FROM `users`  WHERE `users`.`type` IN ('Provider')  ORDER BY `users`.`id` ASC LIMIT 1
Srikala B
  • 3
  • 2