Rails如何从模型中猜出表名?

时间:2013-09-18 07:58:53

标签: ruby-on-rails

我搞乱了我的rails数据库,在那一点上有点迷失了。 一切都开始的时候,我意识到我的一个表名并没有像其他表那样结束。 (我真的不知道为什么,因为我所有的其他表都以's'为前缀) 所以我尝试重命名并进行迁移:

rename_table :funnel_data, :funnel_datas

有关信息,相应的模型称为FunnelData

class FunnelData < ActiveRecord::Base
   ...
end

因此迁移似乎完成了它的工作,并且没有错误地运行。

但现在,在控制台中,我得到了以下内容:

2.0.0-p247 :014 > FunnelData
 => FunnelData(Table doesn't exist)

我检查了我的数据库,表funnel_datas确实存在!

所以它引出了我的问题:Rails如何知道表的“新”名称?我该如何解决我的情况? 感谢。


更新:好的,现在我知道“数据”是“数据”的复数形式,我回滚了我的迁移,并试图按照我的方式,但现在我得到一个奇怪的行为

首先,让我们介绍另一个类:

class FunnelStage < ActiveRecord::Base
    has_many :funnel_data
    (...)
end

我的控制台说:

2.0.0-p247 :046 > f = FunnelStage.first
  FunnelStage Load (0.3ms)  SELECT `funnel_stages`.* FROM `funnel_stages` ORDER BY `funnel_stages`.`id` ASC LIMIT 1
 => #<FunnelStage id: 1, name: "Inquiries", order: 100, created_at: "2013-09-14 23:08:55", updated_at: "2013-09-14 23:08:55">
2.0.0-p247 :047 > f.funnel_dat
f.funnel_data        f.funnel_data=       f.funnel_datum_ids   f.funnel_datum_ids=
2.0.0-p247 :047 > f.funnel_data
NameError: uninitialized constant FunnelStage::FunnelDatum
        from /usr/local/rvm/gems/ruby-2.0.0-p247@rails4test/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:125:in `compute_type'
        from /usr/local/rvm/gems/ruby-2.0.0-p247@rails4test/gems/activerecord-4.0.0/lib/active_record/reflection.rb:178:in `klass'
        (...)
        from bin/rails:4:in `<main>'
2.0.0-p247 :048 > f.funnel_datum_ids
NameError: uninitialized constant FunnelStage::FunnelDatum
        from /usr/local/rvm/gems/ruby-2.0.0-p247@rails4test/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:125:in `compute_type'
        from /usr/local/rvm/gems/ruby-2.0.0-p247@rails4test/gems/activerecord-4.0.0/lib/active_record/reflection.rb:178:in `klass'
        (...)
        from bin/rails:4:in `<main>'

现在,Rails说拉丁语? (数据/基准...)

编辑和回答:好的,我自己想出来了。 Rails很难理解这种关联,因为它试图将“funnel_data”单独化为一个全新的“funnel_datum”名称(这将是正确的btw)

所以我不得不写:

class FunnelStage < ActiveRecord::Base
    has_many :funnel_data, class_name: "FunnelData"
    (...)
end

让它发挥作用。

非常感谢帮助我理解的所有人...

4 个答案:

答案 0 :(得分:3)

要解决您的问题,只需在模型定义下方添加:self.table_name = "funnel_datas"


在幕后,ActiveRecord使用方法#tableize。从指南:

  

方法tableize#underscore,后跟#pluralize

     

根据经验,tableize返回与简单情况下给定模型对应的表名。 Active Record中的实际实现确实不是直接表,因为它还会对类名进行去模式化并检查可能影响返回字符串的一些选项。

Pluralize,默认情况下使用常用英语变形来获得单词的复数形式,但"data"是复数形式。所以:

> "FunnelData".underscore #=> "funnel_data"
> "funnel_data".pluralize #=> "funnel_data"

因此,您的模型默认会查找"funnel_data"表。

答案 1 :(得分:1)

那是因为“数据”是一个不可数字,而rails知道它:

> "data".pluralize
"data"

因此,您的表格应命名为“funnel_data”。

答案 2 :(得分:1)

"user".pluralize
=> "users"

但是:

"data".pluralize
=> "data"

如果你想使用funnel_datas表名:

class FunnelData < ActiveRecord::Base
  set_table_name "funnel_datas"
end

答案 3 :(得分:0)

在rails类名中复数是表名,所以funnel_data复数是funnel_data所以不需要更改表名。