Ruby on Rails Cheetsheet for Migration


Ruby on Rails로 API 작업시 자주 검색해보는 내용을 정리하려한다.
주로 Active Record라는 Rails에서 사용하는 ORM 관련 내용이다.

1. Generate Model

1.1 Make Model

> rails generate model User name:string age:integer

위 작업에 모든 column에 대해서 자세히 적어줄 필요는 없다. /db/migrate/{timestamp}_create_users.rb 식으로 파일이 생성되므로, 여기서 수정하는게 더 편리하다.

class Users < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.integer :age

      t.references :manager, foreign_key: false, default: nil
      t.references :department, foreign_key: false, null: false
      
      t.timestamps
    end

    add_index :users, [:age, :name], unique: false, name: 'index_age_name'
  end
end

1.2 Define Reference

1.2.1 1:1 or 1:N relation : has_one, has_many, belongs_to

table 간의 relation을 정의 할 경우 reference를 가지고 있어야 한다면 t.reference식으로 정의를 해주면 된다. 새로 model을 만들면서 기존 model에 새로 만들 model의 refernece를 추가해야 할 경우 따로 rails generate migration ...으로 작업해도 되지만, 현재 migration 파일에 추가를 해주는 것도 가능하다. def change안에 create_table과 같은 level로 추가를 해주면 된다.

add_reference :manager, :user, foreign_key: false, index: true, default: nil

1.2.2 M:N relation : hans_and_belongs_to_many

이 경우에는 각각의 table에 refernece column이 있을 필요가 없고, relation table을 생성해 줘야 한다. 따로 migration을 생성해서 해도 되지만, 위 파일에 create_table구문을 하나 더 추가해 줘도 된다. 여기서 주의해야할 사항이 하나 있는데 반드시 model을 ABC의 asc 순서대로 나열을 해야한다. 예를 들어서 itemsitem_options가 있는 경우 s보다 o가 더 앞에 있으므로 item_options_items가 된다. 만약 이 규칙을 어겼을 경우 다음 장에서 볼 has_and_belongs_to_many를 model에 정의해 주는 곳에서 table 명을 따로 적어야 한다.

create_table :managers_users do |t|
  t.references :manager, foreign_key: false, null: false
  t.references :user, foreign_key: false, null: false

  t.timestamps
end

generate migration을 추가하는 식으로 작업할 경우에는 아래와 같은 명령어로 생성이 가능하다.

> rails g migration CreateJoinTableManagersUsers manager user

이 명령어는 아래의 migration code를 생성한다.

class CreateJoinTableManagersUsers < ActiveRecord::Migration[5.2]
  def change
    create_join_table :manager :user do |t|
      # t.index [:manager_id, :user_id]
      # t.index [:user_id, :manager_id]
    end
  end
end

1.3 Run Migration

이제 Database에 적용시키자.

> rake db:migrate

1.4 rollback 등…

  • rollback : rake db:rollback
  • rollback 2 step : rake db:rollback STEP=2
  • redo : rake db:migrate:redo STEP=3
  • reset and migration : rake db:migrate:reset
  • drop : rake db:drop

여러 개를 순서대로 실행도 가능하다.

> rake db:drop db:create db:migrate db:seed

2. Define Model in detail

위 작업을 하면 Database에 Table이 생기고, /app/models에 model 파일이 생성된다.

현재 user model의 경우 아래의 property를 가진다.

  • id
  • name
  • age
  • manager_id
  • department_id
  • created_at
  • updated_at

아래에 할 작업은 Database에는 직접적으로 영향을 미치지 않지만, Model을 사용함에 있어서 편리함을 준다. 예를 들어 user.departments에 object를 추가하고, 지우는것 만으로 실제로 Database에서 관련 SQL을 실행해준다.

2.1 Define Reference

managerdepartment를 id가 아닌 model의 refernece로 바로 접근을 하려면 그 관계를 model에 자세히 적어주면 된다.

  • has_one : model의 단수명으로 접근이 가능.
  • has_many : model의 복수명으로 array형식으로 접근 가능. (M:N 관계에서도 한쪽 방향으로만 접근을 해도 되는 경우 has_many 정의가 가능하다.)
  • belongs_to, belongs_to_many : model의 단/복수 형태로 접근이 가능.

has_one/many 로 뭔가를 가지는 경우 model에서 직접 reference를 가질 필요가 없다. belongs_to(_many) 로 속하는 쪽에서 reference를 가지고 있으면 접근이 가능하다.

  • has_and_belongs_to_many : model의 복수명으로 array형식으로 접근이 가능하다.

ralation table 명이 규칙대로 하지 않은 경우 (model의 복수형태 명칭의 ABC asc 순이 아닌 경우)에는 table 명을 명시해 줘야 한다.

위 사항 들을 모두 예제로 적어둘테니 참고하면 된다.

belongs_to :department
belongs_to :manager, optional: true

has_many :users, dependent: :destroy
has_many :users
has_many :users, through: :users_managers

has_and_belongs_to_many :managers

2.2 Define Validation

몇가지 예제를 적어둘 테니 참고하면 된다.

validates :name, presence: true
validates :license_number, length: { is: 10 }, numericality: true, allow_nil: true
validates_inclusion_of :method, in: ['direct', 'relative']
validates :name, uniqueness: { scope: :manager_id }, presence: true, allow_blank: false
enum size: { small: 0, medium: 1, large: 2, extra: 3 }

이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)