Rails速習メモ

百万回挫折してるけど再チャレンジ。以前途中までやったRails tutorialを適当になぞりながらここにメモをしていく。

Javascritのランタイムがないとか言われたらとりあえずGemfileに'therubyracer'(デフォルトだとコメントアウトされてる)入れてbundle updateする。

testUnitじゃなくてspecを使うんなら

rails new sample_app --skip-test-unit
rails generate rspec:install

とする。

Railsでセッション変数の暗号化に使用するための、いわゆる秘密トークン (secret token)というのがよくわからないんだけど、privateリポジトリで作れるならデフォルトのやつでよかったりするのかしら。

Undo特集(これは大事っぽい)
 $ rails generate controller FooBars baz quux
 $ rails destroy  controller FooBars baz quux

これによって関連コードも全部なかったことにできる。

 $ rails generate model Foo bar:string baz:integer
 $ rails destroy model Foo

マイグレーション(データベース定義)もなかったことにできる

 $ rake db:migrate
 $ rake db:rollback

最初の状態に戻したい場合は、以下のコマンドを使う

$ rake db:migrate VERSION=0

マイグレーション逐次的に行われ、その番号をVERSION=で指定することによって任意の過去にもどれる。

して、マイグレーション番号のログみたいなのはないのかな。

基本的にモデルを扱わないんだったら、
大きな単位に対してコントローラーを作る(例:静的ページ、など なんらかの意味的ブロック)

rails generate controller StaticPages pageA pageB ... 

すると、ルーティングがroutes.rbに生成されてるのが確認できる(この時点ではGETだけなのかな)。また、app/controller/hoge_fuga_controller.rbに、それぞれのコントローラーが定義されている。
なお、対応するビューも名前で紐付けられていて、
app/view/static_pages/pageA.html.erbみたいなものがすでに生成されているはずでそれがそのままビューになる。そしたらとりあえずlocalhost:3000/static_pages/pageAとかで見れる。静的ならここまで。簡単!

疑問

(多分コレはメモなのであとでまとめるけど)
ビューの.html.erbでシンボルに値を与えてそれを表示するのに、

provide(:symbol "HOGEHOGE")
yield(:symbol)

とかやってるんだけど、普通に変数に値を代入して、それを呼び出しても普通に表示された。あえてコレを使ってる理由はなんなんだろ。
そもそもhtml.erbの中のrubyのスコープ概念どうなってるんだろ。普通に考えればファイル毎になってる気もするけどたしか別の場所で定義されてた変数も参照してた気がするんだよなぁ……
→コントローラー内の各アクションも含まれるっぽい

ヘルパー関数、つまりビューに使用したい関数はapp/helpers/hoge_page_helper.rbもしくはapplication_helper.rbに適当に定義すれば良い。

style_sheet読み込みは

stylesheet_link_tag "application", { media: "all",
                                     "data-turbolinks-track" => true }

のようにする(らしい)。引数は「スタイルシートへのパス」と「メディアタイプ、Turbolink機能のオンオフのハッシュ」らしい。
ここのスタイルシートへのパスが"application"になっているのはassets pipelineというのが関係してるらしい。にしたって相対パスとかじゃなくていいのだろうか。デフォルトで"/assets/を参照することになってたりするのだろうか。

bootstrapはとりあえず飛ばす……素でSass書けるのならとりあえずそれにしたい……

全体に適用するcss(sass)は
app/assets/stylesheets/custom.css.scss
に書く感じなのかな

と思ったらasset pipelineについて体系的な説明があった。いわく、

最近のRailsに追加された機能の中で最も特筆すべき機能のひとつは、CSSJavaScript、画像などの静的コンテンツの生産性と管理を大幅に強化する「Asset Pipeline」です

とのことらしい。ディレクトリは、
app/assets: 現在のアプリケーション固有のアセット
lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
vendor/assets: サードパーティのアセット
という感じになっているようだ。

厳密な感じのルーティングの記法についてもあんまりよくわかんない……

ユーザーは認証とか色々ダルいのでMicropost(要するにtweet)モデルを使って簡単に実験してみる。

app/models/hoge.rbの中のActiveRecord:Baseを継承したクラスはvalidateやらのメソッドを持っており、大体そこでどうにかできる。(validates関数でググったほうが良さそう)

入力フォームについては、form_forというのを使うのが良さそう。
予めアクション内で例えば

@mp = Micropost.new

とかしといて、該当ビューで

<%= form_for(@user) do |f| %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>

などとするとできるっぽい?

モデルに対して、RESTfulなURL、アクションを定義するなら、

resources :microposts

などとすると、自動的にRESTfulなアクションが利用できるようになる?(Tutorialの表7.1参照)
結局アクション自体は自分で書かないといけないのかな、あとで試してみよう

モデル同士の関連性(belongs_to,has_many等)を定義することで直感的な操作URL及びそれに対するアクションが与えられる。
モデルのクラスのコードに、

belongs_to :user

みたいなことをかけばそれで良い
追記:多分データベースのjoin的なアレに使うid的なのを用意しないといけない。たとえばuser has_many micropostとするんだったらuser_idのようなカラムを持たないと紐付けしようにもできなくなる。

表示は、適当なそのためのパーシャル(部分的HTML、ビューみたいな)のを作ってそれをメイン画面に埋め込めばよい?
Railsには表示するためにrenderメソッドを使う習慣っぽいものがある(気がする)。
たとえば、

<% @users.each do |user| %>
  <%= render user %>
<% end %>

みたいなことを書くと、この場合、Railsは自動的に_user.html.erbという名前のパーシャルを探してくれる。なので適用したいパーシャルを定義しとけばよい。
更にもうちょっと暗黙的にすることもできて、

 <%= render @users %>

だけで、自動的に(たとえばこの例なら)@userをUserのインスタンスだと思ってくれてやっぱり_user.html.erbを探してくれる。めでたい。

とりあえずここまでわかれば(ユーザー認証抜きで)twitter的なことができる?

+α~scaffoldでできること~
rails generate <モデル> カラムA カラムB……

これで主力されたログを見てみると、大体やらないといけないことがわかる

create db/migrate/~day_time~_create_models.rb #マイグレーションのファイル。素だと
create app/models/model.rb #これなんだっけ。
create spec/models/model_spec.rb #spec(テスト)のやつ テストフレームワークにspecを指定したからかな。
route resources :models #前述の通り
create app/controllers/models_controller.rb #コントローラー。
create app/views/models #ビューディレクトリ。以下サブアクションに対応するビュー
create app/views/models /index.html.erb
……
create app/views/models/_form.html.erb #パーシャルかな。
#spec関連は省略。
create app/helpers/models_helper.rb #ヘルパーメソッド。
#この2つよくわかんない。
create app/views/models/index.json.jbuilder
create app/views/models/show.json.jbuilder

#アセット関係
create app/assets/javascripts/user.js.coffee #多分まぁ表示用のcoffeeなんだろうな
create app/assets/stylesheets/users.css.scss #前述。
create app/assets/stylesheets/scaffold.css.scss #これなんだろ。scaffoldのデフォルト用のやつなのかな

これだけ!scaffold怖くない!!!!
デフォルトで作られるRESTな感じのインターフェスはこちら(まあコントローラー見ればわかるんだけど)
HTTPリクエスト| URL| アクション| 用途
GET| /models| index| すべてのモデルを表示するページ
GET| /models/1| show| id=1のモデルを表示するページ
GET| /models/new| new| モデルを新規作成するページ
POST| /models| create| モデルを新規作成するアクション
GET| /models/1/edit| edit| id=1のモデルを編集するページ
PATCH| /models/1| update| id=1のモデルを更新するアクション
DELETE| /models/1| destroy| id=1のモデルを削除するアクション