ActiveRecord invalid table_name
I am 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 as I expected. My ActiveRecord class looks like this:
class Media < ActiveRecord::Base
end
From what I understand, this is how it should look. The ActiveRecord class name must be singular and the table name must be plural. However, when I try to create a new Media object
Media.create filename: "abc.png"
I am getting 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 table_name should be media, not media. If I run the same query directly on the database using "medias" instead of "media", I get the expected result. For all my other models, tablename is pluralized, but for some reason my Media model is an exception. Does anyone know what might be causing this?
source to share
Media is already plural (it is the plural of the medium), so active recording no longer pluralizes, even if people often say "media".
You can check how rails pluralize things from the rails console.
"medium".pluralize #=> "media"
"media".pluralize #=> "media"
If you disagree and don't want to rename your table / model, you can force the active record to be forced to use your table name
class Media < ActiveRecord::Base
self.table_name = "medias"
end
or adjust kinks. Your application should have config / initializers / inflections.rb that describes how to do this.
source to share
Expanding @spickermann's comment, if you want to use Media
as the only value for medias
, you must specify 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 relationship throughout your entire application.
source to share
If you create a model named Media
like this:
rails g model media filename:string
then it ActiveRecord
will generate it as Media
soon as notmedias
Here is the 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
looking for Media
, and you specified the table name as medias
why you are getting the error.
Thus, you can explicitly set the table name in the 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 information see this: http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name
You can also change the table name by creating a new migration file:
class RenameOldTableToNewTable< ActiveRecord:Migration
def change
rename_table :old_table_name, :new_table_name
end
end
source to share