简体   繁体   中英

How to make work single table inheritance and attr_accessible?

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!

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM