ActiveRecord错误的table_name

时间:2015-05-01 13:04:04

标签: ruby-on-rails ruby postgresql activerecord

我试图添加名为Media的ActiveRecord模型。迁移脚本如下所示

class CreateMedias < ActiveRecord::Migration
   def up
      create_table :medias do |t|
         t.string :filename
         t.timestamps null: false
      end
   end
   def down
       drop_table :medias
   end
end

这将在我的PostgreSQL数据库中创建一个名为medias的表,就像我预期的那样。我的ActiveRecord类看起来像这样

class Media < ActiveRecord::Base

end

根据我的理解,它应该是这样的。 ActiveRecord类的名称应为单数,表名称应为复数。但是,当我尝试创建一个新的Media对象时

Media.create filename: "abc.png"

我收到以下错误

ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation    "media" does not exist
LINE 5:                WHERE a.attrelid = '"media"'::regclass
                                      ^
:           SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                 pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
            FROM pg_attribute a LEFT JOIN pg_attrdef d
              ON a.attrelid = d.adrelid AND a.attnum = d.adnum
           WHERE a.attrelid = '"media"'::regclass
             AND a.attnum > 0 AND NOT a.attisdropped
           ORDER BY a.attnum

由于某种原因,ActiveRecord认为table_name应该是media而不是medias。如果我直接在数据库中使用&medias&#39;运行相同的查询。而不是媒体&#39;我得到了预期的结果。对于我的所有其他模型,table_name是复数形式但由于某种原因我的Media模型是一个例外。有谁知道可能导致这种情况的原因?

2 个答案:

答案 0 :(得分:5)

媒体已经是复数(它是复数的媒介),所以即使人们经常说“媒体”,积极的记录也不会进一步复杂化。

您可以从rails控制台检查rails如何使事物多元化

"medium".pluralize #=> "media"
"media".pluralize #=> "media"

如果您强烈反对并且不想重命名您的表格/模型,您可以强制使用活动记录来使用您的表格名称

class Media < ActiveRecord::Base
  self.table_name = "medias"
end

或自定义变形。您的应用应该有一个config / initializers / inflections.rb,其中列出了如何执行此操作。

答案 1 :(得分:1)

如果您生成名称为Media的模型,请执行以下操作:

rails g model media filename:string

然后ActiveRecord会将其生成为media,而不是medias

这是它的迁移文件:

class CreateMedia < ActiveRecord::Migration
  def change
    create_table :media do |t|
      t.string :filename

      t.timestamps null: false
    end
  end
end

在您的情况下,ActiveRecord正在寻找media,并且您已将表名定义为medias,这就是您收到错误的原因。

因此,您可以在模型中明确设置表名:

Rails&gt; = 3.2(包括Rails 4 +):

class Media < ActiveRecord::Base
  self.table_name = "medias"
end

Rails&lt; = 3.1:

class Media < ActiveRecord::Base
  self.set_table_name "medias"
end

有关详细信息,请参阅: http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name

您还可以通过生成新的迁移文件来更改表名:

class RenameOldTableToNewTable< ActiveRecord:Migration
   def change
     rename_table :old_table_name, :new_table_name
   end 
 end