Print
Category: Computer Science

1.Single Table inheritance

Add a column called something_type, for example product_type, person_type, animal_type.

Avoid using the name ‘type’, because it is a very old Ruby keyword, and it can cause confusion.

 

Then define the class method  Klass.inheritance_column.

 

Example:

 

class Cat < ActiveRecord::Base

  has_many :claws, :dependent => :delete_all

  

  def self.inheritance_column

    'animal_type'

  end

end

 

create_table :cats do |t|

  t.column :age,      :integer

  t.column :name,     :string, :limit => 40, :null => false

  t.column :animal_type, :string, :limit => 40;

  t.column :cat_attr,    :string, :limit => 60

  t.column :stripes,     :integer

  t.timestamp

end

 

 

2. Polymorphism

An address can belong to a user or a facility.

 

class Address < ActiveRecord::Base

  belongs_to :owner, polymorphic: true

end

 

class Facility < ActiveRecord::Base

  has_many :addresses, as: :owner

end

 

class User < ActiveRecord::Base

  has_many :addresses, as: :owner

end

 

class CreateAddresses < ActiveRecord::Migration

  def change

    create_table :addresses do |t|

      t.string :street

      t.string :city

      t.string :state

      t.string :zip

      t.string :county_name

      t.string :telephone_number

      t.references :owner, polymorphic: true, index: true

 

      t.timestamps null: false

    end

  end

end

 

 

3. Associations with different names

A message has users as both sender and recipients.

 

class Message < ActiveRecord::Base

  belongs_to :sender, class_name: 'User', foreign_key: 'sender_id'

 

  has_many :messages_users, dependent: :destroy

  has_many :recipients, through: :messages_users

end

 

class User < ActiveRecord::Base

 

  has_many :sent_messages, class_name: 'Message', foreign_key: 'sender_id'

 

  has_many :messages_users

  has_many :received_messages, through: :messages_users

 

end

 

class MessagesUser < ActiveRecord::Base

  belongs_to :received_message, class_name: 'Message', foreign_key: 'message_id'

  belongs_to :recipient, class_name: 'User', foreign_key: 'user_id'

end

 

class CreateMessages < ActiveRecord::Migration

  def change

    create_table :messages do |t|

      t.string :subject

      t.text :content

      t.references :sender

 

      t.timestamps null: false

    end

  end

end

 

class CreateMessagesUsers < ActiveRecord::Migration

  def change

    create_table :messages_users do |t|

      t.references :message

      t.references :user

      t.boolean :read_status, default: false

 

      t.timestamps null: false

    end

  end

end

 

 

4. Create index and foreign key constraints in migration code

 

def create_office_addresses_physicians

  create_table :office_addresses_physicians do |t|

    t.references :office_address, index: true, foreign_key: true

    t.references :physician, index: true, foreign_key: true

 

    t.timestamps null: false

  end

end

 

 

5. Use foreign key constraints to a table with different name, different foreign key convention

A post refers to an author in table users, foreign_key is author_id 

 

def change

  create_table :posts do |t|

    t.references :author, index: true

  end

  add_foreign_key :posts, :users, column: :author_id

end

 

6. Overriding the Naming Conventions

 

ApplicationRecord is Rails5’s new base class. Do not use ActiveRecord::Base.

 

class Product < ApplicationRecord

  self.table_name = "my_products"

end

 

class ProductTest < ActiveSupport::TestCase

  set_fixture_class my_products: Product

  fixtures :my_products

  ...

end

 

 

class Product < ApplicationRecord

  self.primary_key = "product_id"

end