Abris
Abris

Reputation: 1481

ActiveRecord wrong table_name

I'm trying to add an ActiveRecord model called Media. The migration script looks like this

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

This will create a table in my PostgreSQL database called medias just as I expected. My ActiveRecord class looks like this

class Media < ActiveRecord::Base

end

From what I understand this is how it should look like. The name of the ActiveRecord class should in singular and the table name in plural. However, when I try to create a new Media object

Media.create filename: "abc.png"

I get the following error

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

For some reason ActiveRecord thinks that the table_name should be media and not medias. If I run the same query directly in the database with 'medias' instead of 'media' I get the expected result. For all my other models, the table_name is pluralized but for some reason my Media model is an exception. Does anyone know what might cause this?

Upvotes: 3

Views: 2626

Answers (3)

Gagan Gami
Gagan Gami

Reputation: 10251

If you generate model with the name of Media like this:

rails g model media filename:string

then ActiveRecord will generate it's table as media only not medias

Here is it's migration file:

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

      t.timestamps null: false
    end
  end
end

In your case ActiveRecord is looking for media and you have defined table name as medias that's why you are getting an error.

So you can set table name explicitly in model as:

Rails >= 3.2 (including Rails 4+):

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

Rails <= 3.1:

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

For more details please refer this: http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name


You can also change the table name by generating new migration file:

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

Upvotes: 2

Frederick Cheung
Frederick Cheung

Reputation: 84114

Media is a already a plural (it's the plural of medium), so active record pluralizes no further, even if people say "medias" often enough.

You can check how rails pluralizes things from the rails console

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

If you disagree strongly and don't want to rename your table / model, you can either force active record to use your table name

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

or customise the inflections. Your app should have a config/initializers/inflections.rb which sets out how to do this.

Upvotes: 5

Ruby Racer
Ruby Racer

Reputation: 5740

Extending @spickermann's comment, if you want to use Media as singular for medias, you should provide an inflection to declare it.

file: /rails_root/config/initializers/inflections.rb

ActiveSupport::Inflector.inflections do |inflect|
  inflect.plural 'medias', 'media'
end

This way, you will be able to use this singular/plural relation throughout your whole app..

Upvotes: 2

Related Questions