如何使单表继承和attr_accessible工作?

时间:2013-11-09 13:53:23

标签: ruby-on-rails single-table-inheritance

在rails应用程序中,我有一个这样的基本模型:

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

这个模型的继承,如下:

class Provider < User
  belongs_to :user

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

当我这样做时:

Provider.new.user_id

它说NoMethodError: undefined method 'user_id' for #<Provider:0x007f63ec8b3790>

当我做Provider.new时,我有这个:

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

这是我的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

如您所见,无法访问Provider的可访问属性。你有解决方案吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

正如Single Table Inheritance to refer to a child class with its own fields的回答中所讨论的,ActiveRecord单表继承的实现不涉及其他表。所有子类共享同一个表,并依赖type字段来标识子类。这就解释了为什么您的Provider实例仅包含users表中可用的字段,包括Rails为子类支持添加的type字段。您的providers表未使用。

答案 1 :(得分:0)

在数据库级别使用相同的表。通过向现有表添加新列来实现STI。通常名为“type”的新列用于保存信息,无论是“提供者”还是“用户”

以下是模型查询如何转换为SQL查询

当查询用户模型时,根据您的示例,它会搜索“用户”表并包含条件中的所有可用类型值

df["ColC"] = df["ColA"].subtract(df["ColB"], fill_value=0)

当查询Provider模型时,在条件中将type设置为'Provider',因此结果将被过滤。底层数据库表保持不变,即“用户”

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