最近のrails事情 - 4.1!

19
最近のRails事情 - 4.1! author: ‘@ke_tachibana’ about: gem ‘rails’, ‘4.1.0.beta1’ generated_by: ‘slideshow(s9) gem (https://github.com/slideshow-s9/slideshow)’

Upload: kenichi-tachibana

Post on 19-Jan-2015

5.102 views

Category:

Technology


8 download

DESCRIPTION

2014/1/15 Hamamatus.rb #35 での発表に使ったスライドです。

TRANSCRIPT

Page 1: 最近のRails事情 - 4.1!

最近のRails事情 - 4.1!author: ‘@ke_tachibana’

about: gem ‘rails’, ‘4.1.0.beta1’

generated_by: ‘slideshow(s9) gem (https://github.com/slideshow-s9/slideshow)’

Page 2: 最近のRails事情 - 4.1!

Preloader組み込みで色々高速起動railsチーム謹製PreloaderであるSpringがデフォルトで組み込みrails系コマンドの起動の遅さを改善するプログラム初期化処理の終わったプロセスをあらかじめ立ち上げておく仕組み

Page 3: 最近のRails事情 - 4.1!

対応するコマンドrails, rake, rspec, cucumber, testunitあたり

つまり、このへんが高速起動する(2回目から)

rails consolerails generaterake db:migraterake routesrake db:seedrspec spec/models/foo.rb

実際1.5秒が0.3秒くらいになった

Page 4: 最近のRails事情 - 4.1!

注意点railsとrake以外は別のgemに分離されている

Gemfile:

gem 'spring' # これは元から書いてあるgem 'spring-commands-rspec' # これを追加しよう

Page 5: 最近のRails事情 - 4.1!

使い方$ spring binstub rspec # ./binにrspecコマンドが出来る$ bin/rspec # bundle execとspringを通してrspecを実行する

railsコマンドはbin/を付けなくても良い模様rakeコマンドはプロジェクト生成時にbinstubされている模様direnv (https://github.com/zimbatm/direnv) などを使えば、railsディレクトリに入った時だけ./binをPATHに追加したりできる

Page 6: 最近のRails事情 - 4.1!

秘密の設定値を格納するファイルが標準化“config/secrets.yml”

development: secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 #=> これはRails標準のキー my_api_key: FOOBAR # => 好きなのを追加できる

production: my_api_key: <%= ENV['OTHER_API_KEY'] %> #=> これも出来る

取得:

Rails.application.secrets.my_api_key # => 'FOOBAR'

githubなどに入れることを考えるとダミーにしておくerb記法で環境変数からアクセスする

いずれにしてもアプリケーション内での取得方法を統一できる

Page 7: 最近のRails事情 - 4.1!

Viewのバリエーションを自動切り替えsamples_controller.rb:

before_action do request.variant = :tablet if request.user_agent =~ /iPad/end

以下を自動選択:

app/views/samples/index.html.erb/index.html+tablet.erb

misc:

index.html.erbは無いと駄目(当然)index.html+smartphone.erbとかは無くても良い(index.html.erbが使われる)特定のvariantだけredirectとか、もっと細かい制御も可能(詳しくはWebで!)

Page 8: 最近のRails事情 - 4.1!

メールのプレビュー機能が組み込まれた#{Rails.root}/test/mailers/previews/notifier_preview.rb に (/test !)

class NotifierPreview < ActionMailer::Preview def welcome Notifier.welcome(User.first) endend

を置いて

Page 9: 最近のRails事情 - 4.1!

http://localhost:3000/rails/mailers

previewの一覧が!

Page 10: 最近のRails事情 - 4.1!

http://localhost:3000/rails/mailers/notifier/welcome

previewにフォーマットの切り替えまで!(ビューが複数ある場合)

paramsは使えないのでpreviewを動的に変える方法は無いかも

Page 11: 最近のRails事情 - 4.1!

ちなみにダミーSMTPというアプローチも (Rails 4.1とは関係ないが)

ダミーSMTPソフトSMTPを受け入れるが中継する代わりに自分で保持するサーバー。Webやメーラーなどで表示できる。

MailCatcher http://mailcatcher.me/($gem install mailcatcher で入るSinatraアプリケーション)

FakeSMTP http://nilhcem.github.io/FakeSMTP/(Java GUIアプリケーション)

Mailtrap http://mailtrap.io/(オンラインのサービス)

Page 12: 最近のRails事情 - 4.1!

ActiveRecordにenumフィールドがclass Conversation < ActiveRecord::Base enum status: [ :active, :archived ]end

conversation.archived! # statusをarvhivedにするconversation.status = 'archived' # 同じくstatusをarchivedにするconversation.status = 'foo' # ArgumentError: 'foo' is not a valid status

conversation.active? # => false statusがactiveかどうかconversation.status # => “archived” 文字列で返されるconversation.status_before_type_cast # => 0 DBの生の値 Conversation::STATUS # => { "active" => 0, "archived" => 1 }Conversation.archived # => ActiveRecord::Relation statusがarchivedなものだけのscope

Page 13: 最近のRails事情 - 4.1!

miscDBのカラム型はinteger複数の属性が同じ名前の項目を持つときは多分困る

active, vote_activeなどとstatus名を分ける必要がある定義はHashでも良い。むしろ明示した方が良い?

class Conversation < ActiveRecord::Base enum status: { active: 1, archived: 2 }end

whereには数値で与える必要がある Conversation.where(status: 'active').to_sql # => 'SELECT "conversation".* FROM "conversation" WHERE "conversation"."status" = 0' # oh...

Conversation.where(status: 1).to_sql # => 'SELECT "conversation".* FROM "conversation" WHERE "conversation"."status" = 1'

Page 14: 最近のRails事情 - 4.1!

属性名を指定するだけで”pretty”なURLが作れるclass User < ActiveRecord::Base to_param :nameend

index.erb:

<% user = User.new(name: 'myname') %><%= link_to 'Show User', user %>

<a href="/users/1-myname">Show User</a>

先頭にidが付くので、String#to_iの仕様により User.find(params[:id]) はそのまま動く

Page 15: 最近のRails事情 - 4.1!

activerecord/lib/active_record/integration.rb:def to_param(method_name) define_method :to_param do if (default = super()) && (result = send(method_name).to_s).present? "#{default}-#{result.truncate(20, separator: /\s/, omission: nil).parameterize}" else default end endend

日本語は消える20文字以上も消える

Page 16: 最近のRails事情 - 4.1!

User#to_paramを自分で実装しても良いclass User < AR::Base def to_param name endend

Rails 4.1以前からあった仕様上記の場合、controllerではUser.find_by!(name: params[:id])とする

Page 17: 最近のRails事情 - 4.1!

便利メソッド追加(ActiveSupport)

マッチする文字を削除する String#remove

'My name is FOO'.remove(/\s/) # => 'MynameisFOO'

Dateが属する週、月、四半期、年の範囲をRangeで

day = Date.new(2014, 1, 15)day.all_week # => Mon, 13 Jan 2014..Sun, 19 Jan 2014day.all_month # => Wed, 01 Jan 2014..Fri, 31 Jan 2014day.all_quarter # => Wed, 01 Jan 2014..Mon, 31 Mar 2014day.all_year # => Wed, 01 Jan 2014..Wed, 31 Dec 2014

複数のキャッシュを一度にfetchするfetch_multi

Rails.cache.write(:a, 1)Rails.cache.write(:b, 2)Rails.cache.fetch_multi(:a, :b) # => [1, 2]

Page 18: 最近のRails事情 - 4.1!

その他Queue APIはまた入らなかったModule#concerningを省略したが、結構大事な気がするモデル内部をグループ化して名前を付ける機能Product内部をSearchingとPurchasingとReviewingに分類したりする

時間をstubするテストヘルパ#travel, #travel_to が入ったはずだが、RSpecでは使えない?rake db:test:prepare タスクが消えたらしいテスト実行時に必ず暗黙的にDBをセットアップするようになったらしい外部キーなど必須のレガシーDBではどうするかまだ調査中

Page 19: 最近のRails事情 - 4.1!

ありがとうございました