Ruby
study resource
https://github.com/JuanitoFatas/rails-style-guide/blob/master/README-zhTW.md rails code style
https://ihower.tw/rails/ ROR中文實戰聖經!
https://guides.ruby.tw/
https://www.gitbook.com/book/airsonwayne/rocodev-practice-series/details 邁向 Rails 高級新手
http://railsfun.tw/ rails論壇
https://pragprog.com/book/rails51/agile-web-development-with-rails-5-1
https://kaochenlong.com/2014/12/28/ruby-for-rails/ ruby語法放大鏡
ruby syntax style
https://github.com/bbatsov/ruby-style-guide#indent-conditional-assignment
ROR install
$ ruby -e "$(curl -fsSL \
https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install ruby
$ brew install rbenv ruby-build
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ ruby -v
$ gem install rails --version=5.1.3 --no-ri --no-rdoc
$ brew install yarn
$ brew install chromedriver
疑問
block
string.unpack
hash 常規用那一種?
inst_section = {
:cello => 'string',
:clarinet => 'woodwind',
}
inst_section = {
cello: 'string', ...}
Action Cable 機制不熟
turbolinks ?
p.186
rails51/depot_p/app/models/order.rb
class Order < ApplicationRecord
# ...
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
if stale?(@latest_order) ??
rails 常用指令
rails new depot 建新專案
bin/rails generate controller {controller name}
bin/rails generate scaffold Product \
title:string description:text image_url:string price:decimal 鷹架 build controller,model,view,unit test code
bin/rails db:create 建立DB
(bin/rails|rake) db:migrate 建立資料表
bin/rails db:seed 喂測試資料
bin/rails db:rollback
bin/rails server 啟動test網站
bin/rails test 整體單元測試
bin/rails test:models 測試model
bundle install 安裝gem
bin/rails webpacker:install
yarn install
bin/rails webpacker:install:react
Gem list (order by important)
- aasm : State machines for Ruby classes (plain Ruby, ActiveRecord, Mongoid)
- active_hash : ActiveHash is a simple base class that allows you to use a ruby hash as a readonly datasource for an ActiveRecord-like model.
- bootstrap : The most popular HTML, CSS, and JavaScript framework for developing responsive
- bulk_insert : Faster inserts! Insert N records in a single statement.
- capistrano : Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. (部署用)
- capistrano-rails
- capistrano-passenger
- capistrano-rvm
- capistrano-slackify
- carrierwave : Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends.**
- cells-erb : Tilt binding for Erbse. Erbse is a modern Erubis implementation with block support.
- cells-rails : Convenient Rails support for Cells.
- country_select : Provides a simple helper to get an HTML select list of countries.
- devise : Devise is a flexible authentication solution for Rails based on Warden
- dry-types : Type system for Ruby supporting coercions, constraints and complex types like structs
- faraday : Simple, but flexible HTTP client library, with support for multiple backends.
- fog-aws : This library can be used as a module for
fog
or as standalone provider to use the Amazon Web Services in applications - htmlentities : A module for encoding and decoding (X)HTML entities.
- httparty : Makes http fun! Also, makes consuming restful web services dead easy.
- json-schema : Ruby JSON Schema Validator
- kaminari : Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 4+
- letter_opener : Preview mail in the browser instead of sending.
- mini_magick : Manipulate images with minimal use of memory via ImageMagick / GraphicsMagick
- paper_trail : Track changes to your models' data. Good for auditing or versioning.
- paypal-sdk-adaptiveaccounts :
- paypal-sdk-rest :
- rspec-rails : a testing framework
- react-rails :
- redis-rails :
- rubrowser : a visualizer for ruby code
- seed-fu : Advanced seed data handling for Rails
- sentry-raven :
- settingslogic : A simple and straightforward settings solution that uses an ERB enabled YAML file and a singleton design pattern.
- sidekiq-bus : A simple event bus on top of Sidekiq. Publish and subscribe to events as they occur through a queue
- simple_form : Forms made easy!
- stripe : Stripe is the easiest way to accept payments online. See https://stripe.com for details. API Docuemtn: https://stripe.com/docs/api/ruby#intro
- stripe_event : Stripe webhook integration for Rails applications. See: https://github.com/integrallis/stripe_event
- trailblazer : A high-level architecture for Ruby introducing new abstractions such as operations, form objects or policies.
- trailblazer-cells
- trailblazer-rails
- vanity : is an Experiment Driven Development framework for Rails.
whenever : Clean ruby syntax for writing and deploying cron jobs.
pg : postgresql
- puma : A Ruby Web Server Built For Concurrency
- breakpoint :
- tzinfo-data :
Rspec
https://relishapp.com/rspec/rspec-core/v/3-7/docs/example-groups/basic-structure-describe-it
Factory-girl
http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md https://github.com/thoughtbot/factory_bot GitHub http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md Getting Started http://rubyist.marsz.tw/blog/2012-02-06/factory-girl-rails-intro/
Trailblazer
Trailblazer 的目的是將原先 Rails 單純 MVC 架構下可能會散亂在 Controller / Model 層的商業邏輯,集中起來包在 Operation 的概念裡,(在理想狀況下)分別簡化日益肥大的 Controller / Model / View 邏輯:
Controller
讓 controller 單純負責傳送 current_user / resource 到正確的 operation 並視操作結果導向相對應的路由
權限控管交給 Policy 處理,用 controller 塞給 operation 的 current_user 配合 operation 的 model!(param) method 所傳回之 resource 兩者之間的關係去做權限控管
商業邏輯封裝在 Operation 裡
只傳送成功執行 operation 後的 @model (resource) 給 view
Model
讓 Model 單純負責與資料庫之間的溝通,原先的 Validation 改由 Contract 操作
本來可能塞在 Model 裡的各種 before_validation before_save 等 callbacks 拉出來改在 operation 的 process 裡面操作
本來塞在 "fat model" 裡的商業邏輯,一樣抽出來寫在相對應的 operation 裡
View
減少原先直接吃 controller instance variables 並在 erb 或 global helper 裡面塞各種邏輯判斷的情況,把 controller 傳過來的 @model 傳到相對應的 Cell 裡面去處理。
Cell 結合 Reform 可以做出複雜的 form 格式,由於已經透過抽象化,所以複雜 form 的參數不再直接對應到 Model 上,而是綁在 contract attribute 上,屬性的自由度可以大幅增加,透過 prepopulator 去準備需要呈現的 @contract,餵進 controller 的參數也可以透過 populator 做處理,讓 Cell 可以用 form_for 的方式去打包 contract 以簡化 view code
keywords
- class: class
- attr_accessor :variable_name : 變數get、set (attr_reader , attr_writer)
- INSTANCECLASS.instance_methods : 反射class實例method
- self.methods : 反射class實例method
- def: function define
- initialize: class初始化
- if ... elsif ... else ... end
- $! #表示异常信息
- $@ #表示异常出现的代码位置
- def self.methodname() : 類方法
- private :methodName : private方法
- protected :methodName : protected方法
- INSTANCECLASS.freeze : 凍結 (有解凍的吧?)
- CLASS_NAME.new vs CLASS_NAME.allocate : allocate 不調用initialize
- OpenStruck, Struck : http://motion-express.com/blog/20150406-ruby-struct-and-ostruct, http://railsfun.tw/t/method-block-yield-proc-lambda/110
- .ancestors 列出祖先class
- .included_modules
- &. http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
ActiveRecord
官方API https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by
CMD
rails g model event name:string description:text is_public:boolean capacity:integer
rails g migration migration_name (ex: create_{table_name} or add_{column_name}_to_{table_name}, remove_{column}_from_{table_name})
rake db:reset (total schema rebuild)
rake db:migrate 執行Migration動作
rake db:rollback STEP=n 回復上N個 Migration 動作
rake db:migrate:status 顯示目前 migrations 執行的情況
rake db:create 依照目前的 RAILS_ENV 環境建立資料庫
rake db:create:all 建立所有環境的資料庫
rake db:drop 依照目前的 RAILS_ENV 環境刪除資料庫
rake db:drop:all 刪除所有環境的資料庫
rake db:migrate:up VERSION=20080906120000 執行特定版本的Migration
rake db:migrate:down VERSION=20080906120000 回復特定版本的Migration
rake db:migrate:redo
rake db:seed 執行 db/seeds.rb 載入種子資料
rake db:version 目前資料庫的Migration版本
如果需要指定Rails環境,例如production,可以輸入 RAILS_ENV=production rake db:migrate
migration :bulk
https://aaronlasseigne.com/2012/06/05/faster-activerecord-migrations-using-change-table-bulk/
RELATION
migrate:
polymorphic: ( t.references :userable, polymorphic: true, index: true )
references: ( t.references :organization )
default: ( t.integer :role, default: 3 )
t.timestamps
models:
has_many: ( has_many :organizationships, as: :userable, class_name: '::User::Organizationship', dependent: :destroy )
enum: ( enum role: { admin: 0, editor: 1, project_manager: 2, basic_user: 3 } )
belongs_to:
( belongs_to :userable, polymorphic: true )
( belongs_to :organization, class_name: '::User::Organization' )
READ
{model_name}.find( {id} )
{model_name}.where( where column condition... )
CREATE
{model_name}.new( column datas... ) 建立資料,需要 .save
{model_name}.{has_many_model_name}.build( column datas... ) 建立資料,需要 .save
{model_name}.build_{has_one_model_name}( column datas... )
{model_name}.{has_many_model_name}.create( {id} ) 直接建立資料並存檔
{model_name}.create_{has_one_model_name}( column datas... ) TODO?:重覆建時 會有dirty資料
{model_name}.{has_many_model_name} << {has_many_model} 建立關鏈
UPDATE
update_all(author: 'David')
DELETE
{model_name}.{has_many_model_name}.destroy_all # 一筆一筆刪除 e 的 attendee,並觸發 attendee 的 destroy 回呼 (!!真的從資料表中刪除)
{model_name}.{has_many_model_name}.delete #一次砍掉 e 的所有 attendees,不會觸發個別 attendee 的 destroy 回呼 (!!只update關鍵欄位值為null)
About class
Include, Extend, Load, Require 使用區 https://ruby-china.org/topics/25706
.irbrc
#record irb console command to log file
Kernel.at_exit {
File.open("irb.log", "a") do |f|
f << "\n#{Time.now.to_s}\n"
f << Readline::HISTORY.to_a.join("\n")
end
}