iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
自我挑戰組

初級紅寶石魔法師心得分享。系列 第 10

D-20. 預設更改DBMS 、bundle指令 、Gemfile && Reverse String II && III

開始Rails new前新手可以先做的。


Rails是允許客制生成框架內容的,下方即為指令,會出現很多客製化選項,今天稍微試玩一下。

$ rails new -h
-d, [--database=DATABASE]
# Preconfigure for selected database (options: mysql/postgresql/sqlite3/oracle/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc)
# Default: sqlite3

-d這個部分,就是選擇要使用的DBMS,除非選擇製作靜態網頁,不然不可能不使用DB
如果是練習包括會部署,一般免費伺服器都有支援mysqlpostgresql

靜態網頁無連接資料庫,使用者無法改變或建立資料,例如加入會員之類。
動態網頁具有資料傳輸功能,需伺服器與DB共同運作,才能有會員,建立修改或評論文章等工能。
兩者可同時存在於同伺服器,也可查詢偽靜態頁面等相關文章。

-T

-T, [--skip-test], [--no-skip-test]                        # Skip test files
    [--skip-system-test], [--no-skip-system-test]          # Skip system test files

TDD是一件非常好的行為,但當rails generate時常常自動多出來的test files不一定需要,可以skip

rails new非常便宜。
就來試試

$ rails new your_project_name -d postgresql --skip-test
或
$ rails new your_project_name --database=postgresql -T

可以發現project/config/database.yml檔案設定的DB是選用pgsql了,gem也有安裝。rails generatecontroller或model也不會再出現test相關檔案。

如果已經rails new才想改DB

rails db:system:change --to=postgresql
rails db:system:change --to=mysql
rails db:system:change --to=sqlite3
rails db:system:change --to=oracle
rails db:system:change --to=frontbase
rails db:system:change --to=sqlserver
rails db:system:change --to=jdbc

第一次幫自己的專案換DBMS還去複製貼上人家的/config/database.yml設定檔,淚奔
這是我做這個紀錄的原因....

記得

rails db:create                          # Creates the database from DATABASE_URL or...

rails db:migrate                         # Migrate the database (options: VERSION=x,...
#or
rails db:schema:load                     # Loads a database schema file (either db/s...

GemfileGemfile.lock

bundlebundle installbundle exec

拿到一個project先看README.md看看作者有沒有提醒什麼,接著通常就會bundle
厲害一點的就bundle exec ......

$ gem list
#看b開頭部分
bundler (2.2.6, default: 2.1.4)

bundlebundler這個gem的指令,默認執行install指令。所以基本上為了安裝gembundlebundle install沒有差別的。

但如果是要使用bundle install後面可以附加的指令時,或者說需要更符合自己的要求安裝時則需用bundle install

#沒去看,不會知道還有這麼多選項。菜鳥我玩過的也不多。
bundle install [--binstubs[=DIRECTORY]]
                 [--clean]
                 [--deployment]
                 [--frozen]
                 [--full-index]
                 [--gemfile=GEMFILE]
                 [--jobs=NUMBER]
                 [--local]
                 [--no-cache]
                 [--no-prune]
                 [--path PATH]
                 [--quiet]
                 [--redownload]  #即使本機有也且可用,還是要下載一次
                 [--retry=NUMBER] #家裡網路不好,重試次數
                 [--shebang]
                 [--standalone[=GROUP[ GROUP...]]]
                 [--system]
                 [--trust-policy=POLICY]
                 [--with=GROUP[ GROUP...]]
                 [--without=GROUP[ GROUP...]]

bundle exec

Execute a command in the context of the bundle
畢竟bundle完通常就跑db:migrate所以bundle exec rake db:migrate不是更方便?

bundlebundler依照Gemfile檔內要求安裝所需gem,若本機沒有則會下載,若Gemfile內沒有特別標注PATH或版本號,例如'~> 6.1.3', '>= 6.1.3.2'bundler會協助下載專案中可用的最穩定的新版本。

bundle install則是對bundlerbundle時可以提出其他要求指令,例如bundle install --redownload,可以要求即使電腦裡已有也要再下載安裝一次。

補充:何為最穩定的新版本。
bundler會幫忙檢查相容性,以及各種需要互相協助的gem是不是版本相符,如果指定版本號相衝或有問題,bundler都會做提醒及建議安裝版本。如不指定版本號,會下載無beta的最新版本。

bundler 官網 https://bundler.io/

Gemfile是許願池,Gemfile.lock是實現了哪些願望。
可以看到bundle install甚至可以指定GemfileGemfile.lock才是真正紀錄bundler安裝了哪些gem資訊的地方。
Gemfile像是展示目前專案需有哪些gem協助運行,bundler會依照這份清單協助安裝。

Gemfile長相

#告訴`bundler`去哪找
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
#Ruby版本號,用哪個版本開的就會記哪個版本,也可以new時選定。
ruby '2.7.3'
#這邊開始是放產品區(production)所需的`gem`,習慣上不會出現單純測試用或單純開發用的gem。

group :development, :test do
#放開發與測試都需要的gem
end

group :development do
#習慣上只放單純開發用gem
end

group :test do
#習慣上只放test用gem
end

Rails new還可以這麼做

RailsGuides
Rails Application Templates

To apply a template, you need to provide the Rails generator with the location of the template you wish to apply using the -m option. This can either be a path to a file or a URL.

$ rails new blog -m ~/template.rb
$ rails new blog -m http://example.com/template.rb

官網下有template.rb每一個部分的簡單講解。

是的Rails有可以客製化模板(Template),讓你rails new時可以生出跟自己製作的Template一樣的內容。網路上也有大神們分享自己的模板,其README.md檔都有告知自己裝了那些gem,如果只是簡單想做一個不用反覆裝gem的template.rb而已,可以嘗試看看。


今天的
leetcode557.Reverse String III
leetcode541.Reverse String II

leetcode557.Reverse String III
題目連結:https://leetcode.com/problems/reverse-words-in-a-string-iii/
題目重點:單純的字串拆分反轉合併。 旋轉 跳躍 我閉著眼

def reverse_words(s)

end

p reverse_words("Let's take LeetCode contest") #=> "s'teL ekat edoCteeL tsetnoc"
p reverse_words("God Ding") #=> "doG gniD"

看到反轉,應該就直覺反應用reverse

#Array
 :022 > [1, 2, 3, 4, 5].reverse
 => [5, 4, 3, 2, 1]
 :032 > "Let's take LeetCode contest".split
 => ["Let's", "take", "LeetCode", "contest"]
 :034 > ["Let's", "take", "LeetCode", "contest"].map(&:reverse)
 => ["s'teL", "ekat", "edoCteeL", "tsetnoc"]

#單純記得Array部分跟可以枚舉元素反轉應該就解得出了。
def reverse_words(s)
  s.split.map(&:reverse).join(" ")
end


#但是String用reverse還有一個特性。
:030 > "abcde".reverse
 => "edcba"
#字串中間有空格會這樣
:031 > "abc def".reverse
 => "fed cba"
:032 > "Let's take LeetCode contest".reverse
 => "tsetnoc edoCteeL ekat s'teL"
:033 > "tsetnoc edoCteeL ekat s'teL".split
 => ["tsetnoc", "edoCteeL", "ekat", "s'teL"]
:034 > ["tsetnoc", "edoCteeL", "ekat", "s'teL"].reverse
 => ["s'teL", "ekat", "edoCteeL", "tsetnoc"]

def reverse_words(s)
  s.reverse.split.reverse.join(" ")
end

leetcode541.Reverse String II
題目連結:https://leetcode.com/problems/reverse-string-ii/
題目重點:看清楚那個k的意思,其實是每2*k一組,每一組的1與2對調。

def reverse_str(s, k)

end

p reverse_str("abcdefg", 2) #=> "bacdfeg"
p reverse_str("abcd", 2) #=> "bacd"

看不懂其實是2*k一組時時,II時III還難。
這題會用到StringArrayRange的隱藏特性。
雖然都解Easy但是看多了,越來越了解duck typing

:047 > str = "12345"
 => "12345"
 :048 > str[0..1] = str[0..1].reverse
 => "21"
 :049 > str
 => "21345"

了解後,就是看怎麼把字串分成2*k一組了。

:051 > "abcdefg".split("")
 => ["a", "b", "c", "d", "e", "f", "g"]
 :052 > "abcdefg".chars
 => ["a", "b", "c", "d", "e", "f", "g"]

~~對象是Array,找Array的方法吧。~~結果在Enumerable,需要枚舉請找枚舉!

each_slice(n) { ... } → nilclick to toggle source
each_slice(n) → an_enumerator
Iterates the given block for each slice of elements. If no block is given, returns an enumerator.

:053 > ["a", "b", "c", "d", "e", "f", "g"].each_slice(2*2).map(&:join)
 => ["abcd", "efg"]

OK!

:059 > ["abcd", "efg"].each{|str| str[0..2-1] = str[0..2-1].reverse}
 => ["bacd", "feg"]

整理後

def reverse_str(s, k)
  s_arr = s.chars.each_slice(2*k).map(&:join)
  s_arr.each{|str| str[0..k-1] = str[0..k-1].reverse}
  s_arr.join(" ")
end

今天提到的
1.bundlebundle installbundle exec
2.GemfileGemfile.lock差異
3.leetcode557.Reverse String III && leetcode541.Reverse String II


上一篇
D-21. & 、meta programming & Monkey patch
下一篇
D-19. Git中的tag 、Git flow && Array Partition I
系列文
初級紅寶石魔法師心得分享。30

尚未有邦友留言

立即登入留言