How to Convert Activerecord Table Name to Model Class Name

How to convert ActiveRecord table name to model class name

I did it!

This returns a hash in the form of "table_name" => "model_class_name".

Hash[ObjectSpace.enum_for(:each_object, class << ActiveRecord::Base; 
self; end).to_a.reject{|c| c == ActiveRecord::Base}.collect{
|c| [c.table_name, c.name]}]

EDIT: Better version (works with Rails 3 only):

Hash[ActiveRecord::Base.send(:descendants).collect{|c| [c.table_name, c.name]}]

Please note not all your model classes are always loaded. To load them all before creating such a hash do this:

Dir.foreach("#{RAILS_ROOT}/app/models") { |f| require f if f =~ /.*\.rb/ }

Nice.

How do I explicitly specify a Model's table-name mapping in Rails?

Rails >= 3.2 (including Rails 4+ and 5+):

class Countries < ActiveRecord::Base
self.table_name = "cc"
end

Rails <= 3.1:

class Countries < ActiveRecord::Base
self.set_table_name "cc"
...
end

Rails 3 joins table and model naming conventions

Your question is not completely clear to me.

By Rails conventions, model names are singular and written in camel case, for instance InstructionProduct. Each model matches a table in the database with the same words, down-cased, separated by '_' and in plural. instruction_products for the provided example.

Look at the following example using has_many:

class User < ActiveRecord::Base
has_many :contacts
end

class Contact < ActiveRecord::Base
belong_to :name
end

user = User.find(1)
user.contacts # returns an array of all the associated objects

When doing user.contacts, contacts is not the table name. It's the collection method, a placeholder for the symbol passed in the has_many method (please follow the has_many link and read what documentation says about has_many). Another name could be used, though:

class User < ActiveRecord::Base
has_many :personal_contacts, class_name: 'Contact' #, foreign_key: :contact_id
end

user = User.find(1)
user.personal_contacts

The class_name and foreign_key are required because rails conventions are not being followed. When using has_many :personal_contacts rails expects that personal_contacts will return an array of PersonalContact.

In Ruby you must start a class name with a capital word, so it is not possible to create a class named instruction_product. If you want to provide a name that does not follow the Rails convention, which I don't recommend, you will need to inform rails about the new table name:

Class AdminUser
self.table_name = "users"
end

Update 1:

As you already know, the convention states that the model should be declared as singular (class InstructionProduct instead class InstructionsProducts. However its just a convention. When a class inherits from ActiveRecord::Base, and a sql query is generated, ActiveRecord lowercases the class name, separates the words by _, converts to a plural name and uses it as the table name (mainly rails uses InstructionsProducts.model_name.plural which returns instructions_products).

You are assuming that singular actually does a name translation to singular, even if it's written in plural, but it doesn't. It assumes that you are using the convention, and mainly returns the class name underscored.

Looking at the rails source code (ActiveModel::Name), ActiveSupport::Inflector.underscore seems to be used (I just did a very superficial investigation, I have to admit). You can see how underscore works at documentation.

Class name to table name ambiguity

use self.table_name to assign custom table name

class PlanetOsmLine < ActiveRecord::Base
self.table_name = "planet_osm_line"
end

Rename single table inheritance rails model class name without changing existing data

This is how you could do it:

  1. Create ULD < Component component/file that is a copy of Uld < Component. I.e. have 2 components, don't remove Uld
  2. In places where you previously fetched Uld make it so that now you fetch records where type is Uld or ULD
  3. In places where you created new Uld records make it so that it instead creates new ULD records
  4. Deploy these changes without any migrations, this way your servers will be backwards compatible with Uld but would also work with ULD
  5. Deploy your migration now
  6. Finally, remove all the mentions/files related to the old Uld and deploy again

How to re-name a ActiveRecord Model which can automatically change the table name in DB?

I would recommend the following:

  1. Change manually the Active Record model class into Train

  2. Make migration to change the database table name from cars to trains

  3. Make good search to change references from Car to Train.

If you have constantly the need to change database table names, you might want to reconsider naming the tables more abstact way. Like in this case you could have table called vehicles and have the "type" field specifying the type (for instance: car or train).



Related Topics



Leave a reply



Submit