【问题标题】:Rails Single table inheritance problemRails 单表继承问题
【发布时间】:2009-10-16 16:25:30
【问题描述】:

我正在尝试在我的 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 时,我会返回类定义。

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

【问题讨论】:

  • 能否提供触发此错误的语句?
  • 请同时提供创建用户表的迁移。

标签: ruby-on-rails types sti


【解决方案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

但是我没有设法重现您的错误:(

【讨论】:

  • 您的迁移缺少 STI 正常工作所需的 :type 属性。
【解决方案2】:

你有 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">]
>>

【讨论】:

  • 您需要添加一个特殊的列“类型”,ActiveRecord 使用它来跟踪单个表中的子类模型。
【解决方案3】:

查看这个页面,这个问题有很多解决方案(即使在 cmets 中)。

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

【讨论】:

    【解决方案4】:

    由于您显示的堆栈跟踪,我认为问题出在您的模型定义之一中。如果您仍然有问题,请粘贴您的代码,我相信您会得到一个很好的答案。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        不久前我遇到了类似的事情,这个网站提供了帮助:

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

        class User < ActiveRecord::Base
          unloadable
        
          ...
        end
        

        不知道为什么会发生这种情况,因为我无法追踪到任何异常情况。不过,我确实相信这是 STI 的情况。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多