Rails基本介绍(三)--Migration简单操作

周一,要装得认真点~


本篇会说到的。

  1. Why?
  2. 名词单数复数查询。
  3. Migration。

为何还需要再次了解这个Rails中很基本的部分?

基本上开发伴随着Git版控已经是常见的事,但Git控制着的是Project的版本,对於资料库不会操作到。

如果我们建立了Migrate档案并执行後,

$ rails db:migrate

Rails会将里面内容输入对应资料库并记录,即使手动删除或使用

$ rails db:rollback
$ rails db:rollback SETP=?       ?号代表回覆几步。

等指令倒退後再删除,DB内已经建立栏位,要再次输入同名栏位或table就会有被阻止的况状。
因此开发中更改table时,需要有正确的流程,避免table无法顺利更新等状况。

正确使用Migrate很繁琐,但是很安全。


单复数查询

英文不好的我,觉得这两个语法很重要,制作Model,Controller可以少一点时间查字典。

#irb
2.7.3 :002 > require 'active_support/inflector'
2.7.3 :005 > puts "player".pluralize
players
 => nil 
2.7.3 :006 > puts "players".singularize
player

Migration

首先打开专案,进到DB资料夹。
https://ithelp.ithome.com.tw/upload/images/20210817/20135887UdX8jESwRW.png
我们会说到的部分以开发工具会看到的部分做说明。
https://ithelp.ithome.com.tw/upload/images/20210817/20135887jWSAVK78tr.png

我们先建立一个model,请注意我故意Model名输入复数。

$ rails g model players name age:integer homeland
Running via Spring preloader in process 15399
[WARNING] The model name 'players' was recognized as a plural, using the singular 'player' instead. Override with --force-plural or setup custom inflection rules for this noun before running the generator.
      invoke  active_record
      create    db/migrate/20210817060308_create_players.rb
      create    app/models/player.rb
      invoke    test_unit
      create      test/models/player_test.rb
      create      test/fixtures/players.yml

我们先看。

[WARNING] The model name 'players' was recognized as a plural, using the singular 'player' instead. Override with --force-plural or setup custom inflection rules for this noun before running the generator.

虽然框架已经进化到会帮你改单数,但还是请依照单复数正确操作,避免意外,一样test部分我们先略。
看看今天的主角群之一20210817060308_create_players.rb这档案。

class CreatePlayers < ActiveRecord::Migration[6.1]
  def change
    create_table :players do |t|
      t.string :name
      t.integer :age
      t.string :homeland

      t.timestamps
    end
  end
end

养成习惯执行migrate前,检查档案内容。
可以发现name,homeland我没有输入string,代表指令可省略string这个与设值,还有没有其他可省略我不会去记,我只会记如果检查有问题,直接这个档案做修改就可以。

指令只是帮你做出这个编码表格,还没有正式帮你建立资料库。

为了操作,我们先将age的与设值也改一下。

t.string :age

存挡後执行

$ rails db:migrate
== 20210817060308 CreatePlayers: migrating ====================================
-- create_table(:players)
   -> 0.0015s
== 20210817060308 CreatePlayers: migrated (0.0016s) ===========================

可以看到schema.rb长出资料了。

  create_table "players", force: :cascade do |t|
    t.string "name"
    t.string "age"
    t.string "homeland"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
# create_table,新建table

这代表资料库(模式)已经建立,请记得一件事,不要手动里面任何一个字,由Migration来帮你处理。
不要手动修改schema.rb的资料。

create_table,就是第一个常用指令,建立资料表。

改单一栏位资料型态change_column

我後悔了age我还是想用integer型态纪录。
建立migration,以下两个指令请都依序输入。

$ rails g migration player
$ rails g migration player_change_age_integer

新的migrate档案依序长得如下

class Player < ActiveRecord::Migration[6.1]
  def change
  end
end

class PlayerChangeAgeInteger < ActiveRecord::Migration[6.1]
  def change
  end
end

不一样的地方只有class名,这也代表migration後面的成为class名,类别无法重复,所以当建立migrate档案时,migration後面请好好确定,不然也会遇到卡住的状况。
自己选一个删掉吧,也只有这时能手动删migrate档案。(未执行rails db:migrate前)

class PlayerChangeAgeInteger < ActiveRecord::Migration[6.1]
  def change
    change_column :players, :age, :integer
  end
end

#改变栏位 :哪张资料表, :哪一栏名, :改变内容(这次是型态)

执行

$ rails db:migrate

回到schema.rb。可以发现age栏位的改变。

  create_table "players", force: :cascade do |t|
    t.string "name"
    t.integer "age"
    t.string "homeland"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

改单一栏位名 rename_column

$ ails g migration players_name_to_nickname

class PlayersNameToNickname < ActiveRecord::Migration[6.1]
  def change
  end
end

class PlayersNameToNickname < ActiveRecord::Migration[6.1]
  def change
    rename_column :players, :name, :nickname
  end
end
# 单一栏位改名 :table_name, old_name, new_name

如果无误,schema.rb如下

  create_table "players", force: :cascade do |t|
    t.string "nickname"
    t.integer "age"
    t.string "homeland"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

如果一次想三个都改。

修改资料表栏位change_table

$ rails g migration players_three_columns
#格式如下
def change
  change_table :table_name do |t|
    t.rename :old_column1, :new_column1
    t.rename :old_column2, :new_column2
    ...
  end
end
  
#示范
def change
  change_table :players do |t|
    t.rename :nickname, :name
    t.rename :age, :power
    t.rename :homeland, :country
  end
end

如无误,schema.rb应该如下

create_table "players", force: :cascade do |t|
  t.string "name"
  t.integer "power"
  t.string "country"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end

增加栏位add_column

$ rails g migration player_add_column_level

#格式
class PlayerAddColumnLevel < ActiveRecord::Migration[6.1]
  def change
    add_column :table_name, :new_column, :type, :options
  end
end

#option部分可以想成额外带入一些设定,例如是否为唯一(uniq),可否空白,预设值,此部分操作与设值。
#option可以不只一个。
#本次操作
def change
  add_column :players, :level, :integer, :default => 1
end

如正确schema.rb如下

create_table "players", force: :cascade do |t|
  t.string "name"
  t.integer "power"
  t.string "country"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.integer "level", default: 1
end
#这边也应该发现,在schema中,一直都是create_table。

补充修改预设

$ rails g migration players_level_default

class PlayersLevelDefault < ActiveRecord::Migration[6.1]
  def change
    change_column_default :players, :level, 2
  end
end
#change_column_default :table_name, :column_name, default_value
#当然预设条件不只一种,会有其他变化。

#schema.rb
  create_table "players", force: :cascade do |t|
    t.string "name"
    t.integer "power"
    t.string "country"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "level", default: 2
  end

移除栏位remove_column

操作与add_column,不操作了。

  remove_column :table_name, :column_name

移除资料表drop_table

  drop_table :table_name

修改资料表名称rename_table

  rename_table :table_name, :old_name, :new_name

资料表删除与改名,如果共同开发,不大可能是轻易决定。操作方式大同小异。
新手初期应该是在修改预设值,uniq等部分会先卡住一下下。

整理一下

Table相关

新增资料表create_table
移除资料表drop_table
修改资料表名称rename_table
修改资料表栏位change_table

Column相关

新增一个栏位add_column
修改栏位名称rename_column
修改栏位的型态(type)change_column
移除栏位remove_column
change_column_default

当然有更多的指令,要熟练当然只能查手册与多练习,反正rails new很便宜....
Active Record Migrations

新增、移除索引,重要到等关联性再说明。

另外如果自己查资料,看到self.up或down等语法,那属於旧版本操作,以目前开发,会少用到。


分享一个逻辑笑话

老婆: 老公,你觉得家花香还是野花香?
老公: 当然是家花!
老婆: 你一定尝过野花,才知道家花香!
好,我笑点低


<<:  [ JS个人笔记 ] Event Loop事件循环—DAY11

>>:  安装 Debian 11 与呒虾米

IT铁人DAY 24-Chain of Responsibility 责任链模式

  今天要认识的模式是Chain of Responsibility,属於Behavioral De...

待更新

待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更新待更...

企划实现(10)

FB登入 第一步:到FB官网并创建帐号 https://developers.facebook.co...

【後转前要多久】# Day13 CSS - Display: Flex (vs Float)

当没有任何CSS时, HTML预设显示区块元素(block)方式都是 往下一行一行(row)长 HT...

[day25]Vue实作-历史交易查询画面

在昨天的铁人贴文中制作了交易建立的画面,之前也有提到,透过批次,会於日档批次中,定期抓取历史缴费纪录...