Ruby on Railsの入門者用メモ

Ruby on Railsの入門者用メモです。

設計思想

DRY/CoC

コマンド

アプリケーションを作成する。
$ rails new applicationname

WebサーバーのWEBrickを起動する。
$ rails s

Scaffoldでオブジェクトを追加・更新・削除する雛形を生成する。
$ rails g scaffold modelname field:type field:type ...

DBを作成する。
$ rake db:migrate

Gemインストールをスキップして、アプリケーションを作成する。
$ rails new applicationname --skip-bundle

GemFileを設定してGemをインストールする。
$ bundle install

雛形ではなく独自に作成したい場合、Scaffoldではなく1.Model、2.Controller&Viewという順に作成する。
$ rails g model modelname field:type field:type ...
$ rails g controller controllername

現在使用中のDBにアクセスする。テーブル情報を表示する。レコードを表示する。抜ける。
$ rails db
> .schema
> select * from modelnames;
> .exit

コンソールを立ち上げる。抜ける。
$ rails console
> quit

URIを生成する。リソースと実装箇所を表示してくれる。
$ rake routes

・他のモデルに関連付けたモデルを作成する。
$ rails g model modelname field:type anothermodelname:references
$ vi app/model/anothermodelname.rb
has_many :modelnames を追加する

メモ(あとで整理する予定)

・GemFileでGemを管理する
rails sのsはserverの略
rails gのgはgenerateの略
・key:typeでtypeがstringの場合はkeyのみでよい(typeのデフォルトはstringのため)
・modelの名前は先頭大文字で単数形
・controllerの名前は先頭大文字で複数
・createはnew+save
・config/routes.rbでルーティングを設定する
・app/views/layouts/application.html.erbはアプリケーション共通テンプレート
・viewのファイルに書いた内容は<%= yield %>に反映される
・<%=render 'xxxx' %>と書くと、_xxxx.html.erbの内容が埋め込まれる
・フィールドのデフォルト値を定義する場合などは自動生成されるyyyyMMddhhmmss_create_modelnames.rbを書き換えてから、rake db:migrateを実行する。
====ここまでdotinstall

====ここからパーフェクトRails
・modelにはscopeを定義できる。scopeはよく使う検索結果みたいなもの。再利用性と可読性が上がる。default_scopeもあるが、チーム開発では見落としに要注意。
・1対多は、referencesというカラム型を多のほうに追加するマイグレーションを作成し、1のmodelでhas_many、多のmodelでbelongs_toを定義する。
・1対1は、has_manyの代わりにhas_oneを使う。
・多対多は、中間modelを作成し(referencesを2つもつ)、多の2つのmodelでhas_manyを定義する。
 例:BookとAuthorの場合(中間modelがBookAuthor)
 $ rails g model BookAuthor book:references author:references
 class Book < ActiveRecord::Base
  # ...省略...
  has_many :book_authors
  has_many :authors, through: :book_authors
 end
 class Author < ActiveRecord::Base
  # ...省略...
  has_many :book_authors
  has_many :books, through: :book_authors
 end
・バリデーションの「!」があるかないかは、バリデーション失敗時に例外が起こるかどうか。
・コールバックは実行されないメソッドもあるので注意が必要。
enum(Rails4.1以降)は、定数のように扱えるが実体は数値。DBを効率よく使える&可読性向上。
・最も基本的なルーティング
 resources :publishers
・ルーティングの拡張例(/publishers/:publisher_id/books/:idとか親子に、/pulishers/:id/detailとか個別に、/publishers/searchとか全体に)
 resources: publishers do
  resources :books
  member do
  get 'detail'
  end
  collection do
  get 'search'
  end
 end
・StrongParametersで脆弱性を防止
・テンプレートファイルはRAILS_ROOT/app/views/コントローラ名/アクション名.html.erbで検索される
・コンテンツのタイプによって表示を切り替える
 respond_to do |format|
  format.html
  format.csv
 end
・partialテンプレート
 <%= render partial: 'form' %> のようにpartialオプションをつけると、先頭が「_」で始まるファイル名のテンプレートから検索する。
 そのため、partialテンプレートのファイル名は先頭に「_」をつける。
・レイアウト用のテンプレート(メタタグ、ヘッダー、フッターなど)はapp/views/layouts/に配置する。
 デフォルトはapplication.html.erbファイルであり、その中の<%= yield %>にそれぞれのページのコンテンツが展開される。
 特定のレイアウトを使用したい場合はrenderメソッドのlayoutオプションで明示的に指定する。
・variantsで条件によってテンプレートを切り替え。モバイル対応とか。
 コントローラのbefore_actionでvariantsに条件ごとの値(例えば :mobile)を割り当て、通常はshow.html.erbだとすれば、show.html+mobile.erbが選択される。
・テンプレートエンジン
 ・ERB・・・Ruby/Rails標準、HTMLとほぼ同じ
 ・Haml・・・シンプルなインデントでHTML構造を表現
 ・Slim・・・Hamlよりシンプルで高速
・ヘルパー
 モデルから受け取ったデータをユーザーにとってわかりやすいフォーマットに変更する。
 Rails組み込みヘルパー:url_for/form_tag/form_for/stylesheet_link_tag/javascript_include_tag/distance_of_time_in_words_to_now/number_with_delimiter
 独自ヘルパーは、app/helpersに配置し、アプリ全体で使うものならapplication_helper.rb、コントローラごとに使うものならbooks_helper.rbなどとするのが一般的。
json構築にはjbuilderというgemを利用する。最近のRailsプロジェクトにはデフォルトで入っている。
 app/controllers/books_controller.rbで以下のように書いたら
 class BooksController
  def show
  @book = Book.find(params[:id])
  redpond_to do |format|
  format.json
  end
  end
 end
 app/views/books/show.json.jbuilderに以下のように書く
 json.extract! @book, :id, :name, :price, :created_at
 すると、以下のようなjsonが生成される
 {"id":1,"name":"Book 1","price":1000,"created_at":"2014-02-04T05:47:00.114Z"}
 ネストさせたり、if文やunless文も可能。
・アプリケーションの主要なロジックはなるべくモデルに書く。そうすることで、コードが整理される、テストがしやすい、などメリットがある。しかし、アプリケーションの複雑化に伴って、モデルが肥大化した状態「Fat Model」となるため、それは別の方法で整理する必要がある。
・Sidekiq:非同期処理ライブラリ
・Pry:irbをより高機能にしたREPL環境
・pry-rails:Pryをrails cで利用するためのgem、ブレークポイント
・pry-byebug:ステップ実行