Rails单表继承问题

时间:2009-10-16 16:25:31

标签: ruby-on-rails types sti

我正在尝试在我的Rails应用程序中为User模型及其子类Member,Subscriber和Staff设置单表继承。

我有一个模型文件:user.rb,member.rb等

定义了用户模型:class User < ActiveRecord::Base; end; 我将其他模型子类化为:class Member < User; end;等等。

在我的用户表中,我拥有每个类需要的所有字段以及类型字段。现在,当我进入控制台并尝试创建一个说成员或订阅者的新实例时,我收到以下错误:

TypeError: can't dup NilClass from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2184:in 'dup' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2184:in 'scoped_methods' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2188:in 'current_scoped_methods' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2171:in 'scoped?' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2439:in 'send' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2439:in 'initialize' from (irb):6:in 'new' from (irb):6

Rails知道子类模型在那里,因为在我只是调用Member或Subscriber的控制台中,我得到了返回的类定义。

我已经阅读了简单的文档,但我一定错过了什么?

6 个答案:

答案 0 :(得分:1)

我从一个临时应用程序开始尝试,它可以正常工作

这是我的用户模型(User.rb)

class User < ActiveRecord::Base
end

我的会员模特(Member.rb)

class Member < User
end

我有一个迁移文件来创建我的用户表,其中包含:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :name
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

现在启动控制台:

➜  ./script/console     
Loading development environment (Rails 2.3.4)
>> u = User.new
=> #<User id: nil, name: nil, created_at: nil, updated_at: nil>
>> m = Member.new
=> #<Member id: nil, name: nil, created_at: nil, updated_at: nil>
>> m.name="hop"
=> "hop"
>> m.save
=> true

但是我无法重现您的错误:(

答案 1 :(得分:1)

你有一个varchar类型的类型列(ruby中的字符串)吗?尝试以下命令(在新的rails项目中)

class Member < User
end

C:\projects\test\sti>ruby script\generate model user name:string type:string membertype:string
  exists  app/models/
  exists  test/unit/
  exists  test/fixtures/
  create  app/models/user.rb
  create  test/unit/user_test.rb
  create  test/fixtures/users.yml
  create  db/migrate
  create  db/migrate/20091019051506_create_users.rb

C:\projects\test\sti>rake db:migrate
(in C:/projects/test/sti)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0000s
==  CreateUsers: migrated (0.0000s) ===========================================


C:\projects\test\sti>ruby script\console
Loading development environment (Rails 2.3.4)
>> u = User.new
=> #<User id: nil, name: nil, type: nil, membertype: nil, created_at: nil, updated_at: nil>
>> m = Member.new
=> #<Member id: nil, name: nil, type: "Member", membertype: nil, created_at: nil, updated_at: nil>
>> m.name = 'fred'
=> "fred"
>> m.save
=> true
>> u.name = 'rader'
=> "rader"
>> u.save
=> true
>> User.find :all
=> [#<Member id: 1, name: "fred", type: "Member", membertype: nil, created_at: "2009-10-19 05:17:11", updated_at: "2009-10-19 05:17:11">, #<User id: 2, name: "rader", type: nil, membertype: nil, created_at: "2009-10-19 05:17:24", updated_at: "2009-10-19 05:17:24">]
>>

答案 2 :(得分:1)

查看此页面,此问题的解决方案很多(即使在评论中)。

http://strd6.com/2009/04/cant-dup-nilclass-maybe-try-unloadable/

答案 3 :(得分:0)

由于您显示的堆栈跟踪,我认为问题出在您的某个模型定义中。如果您仍然遇到问题,请将代码保留,并且我相信您会得到一个好的答案。

答案 4 :(得分:0)

在我将一些功能提取到插件之后,我确实解决了这个问题。

但是我的情况它是从控制台工作的,所以我确保id重新加载,在init.rb中使用这一行    ActiveSupport::Dependencies.load_once_paths.delete( File.expand_path(File.dirname(__FILE__))+'/app/models')

答案 5 :(得分:0)

我曾经遇到类似的事情,这个网站帮助:

http://www.dansketcher.com/2009/05/11/cant-dup-nilclass/

class User < ActiveRecord::Base
  unloadable

  ...
end

不确定为什么会发生这种情况,因为我无法追踪任何异常情况。我确实认为这是STI的情况。