2014年6月30日月曜日

3-4 Turbolinks

 これは数日前まで知らなかった。
 Turbolinksは、Pjax(pushState + Ajax)を簡単に利用できるようにした仕組み。Pjaxっつーのは、URLを更新するときに変更されるページの一部だけを書き換えることで描画を高速化する。

Turbolinksの動作について

Turbolinksの基本的な動きとしては、jsやCSSに変化が無ければ、タイトルとbodyだけを差し替えてページ描画を高速化させるそうな。

Turbolinksの利用方法と無効にする方法

Rails4では基本的になにも設定しなくてもTurbolinksが動作する。無効にする場合には、下記の行をそれぞれのファイルから削除する。
#app/assets/javascripts/application.js
  //= require turbolinks
#Gemfile
  get 'turbolinks'

Turbolinksを利用するときの注意点

性質上、Turbolinksを考慮して書かれたjavascriptでないと動作しない場合があるので、注意する。

 その他はごく一般的なサイト作りにはまだ必要にならなそうに思うので、レベルが上がったらp125以降を読み直すことにしよう。

 難しくなってきて、文体がですます調になっている。授業で黒板を写している気分。この感覚は全然頭に入っていない証拠。自分がよく知っている。
 一旦テキストを離れて自分であれこれやらないといけない段階かなー。

3-3 Sass

 SassはCSS3を拡張したStylesheetの記述形式。
 こういうの多いんですね。最終的な技術は一緒でコーディングのしやすさや可読性を高めただけ。作業現場ではかなり嬉しいのかな。

 これも割愛。やりながら覚えていこう。

3-2 CoffeeScript

 CoffeeScriptはJavaScriptにコンパイルできるRubyに似た言語。

 ここは必要になったらその都度調べることにして、スキップしよう。

3-1 Sprockets

 3章は、アセット。わからん。まずはSprocketsの動きを学ぶことで、Asset Pipelineの本質を知る。わからん。
 SprocketsはRackベースのアセットパッケージングツールなんだけど、詳しくは10章で。そうすか。
  • アセットファイルにアクセスするためのパスを管理する
  • アセットのコンパイル
  • アセットファイル同士の依存性を管理する

アセットファイルのアクセスパスを管理する

 まずはrails generateを使わずに進めるみたい。sprockets_sampleディレクトリを作ってrails init。これだとGemfileだけ作られるみたい。
bundle init
 その後、Gemfileにsprocketsを追加してインストール。
~/work/sprockets_sample$bundle install --path .bundle
ここでは--pathをつけてインストールしたパッケージがこのディレクトリ内でのみ使えるように指定している。システム全体で使えるようにするには、--systemオプションをつける。.bundleは設定用のディレクトリ。一般的にhiddenにするのかな。
 Railsの設定ファイルであるconfig.ruを作成し、下記を入力する。
require 'sprockets'
map '/assets' do #sprockets利用宣言
  environment = Sprockets::Environment.new
  environment.append_path 'assets/javascripts' #このディレクトリ内のアセットファイル
  environment.append_path 'assets/stylesheets' #このディレクトリ内のアセットファイル
  run environment
end
map '/' do
  run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello World"]]}
end
 で、やっとsprocketsの説明が出てきた。アセットファイルを配置するパスを管理して一つのディレクトリにあるようにアクセスを可能とする機能だそう。つーか、こういうの先に言ってくれないと何の勉強をしているかもわからず辛い。
 どうでもいいけど、眠いとタイプミスだらけであとから無駄に時間を使うことに気づいた。眠いときは寝るか、概要を理解するために本をさらっと読むくらいにしようかな。

Railsでの設定方法

 Railsの〜/assets内はデフォルトでアセットパスが登録されているので設定不要で利用できる。
 足りない場合はconfig/application.rbにアセットパスを追加する。例えば、ルートのconponentsディレクトリをアセットパスに追加する場合はこんな感じ。
  class Application < Rails::Application
    config.assets.path << Rails.root.join("conponents")
  end

コンパイルとAsset Pipeline

 SprocketsはCoffeeScriptとSassっつーJavaScriptとCSSが簡単に書けるスクリプト言語をコンパイルでき、Railsで解釈できるようになっているようです。jsとかCSSってもう古いんですかね。初めてホームページというのを作ったときはhtmlだけで作ったような気がします。その後CSSも使って、便利だけど頭が混乱しました。今はもっと混乱しています。
 Gemfileに必要なパッケージの組み込み。実際にRailsで利用する場合は、右のパッケージを使う。あとJavaScriptが動作する環境が必要。
gem "sprockets"
gem "coffee-script" #coffee-rails
gem "therubyracer"
gem "sass" #sass-rails
  config.ruにはrequireを追加。
require 'coffee-script'
require 'therubyracer'
require 'sass'
 therubyracerはJavaScriptをRuby環境で実行できるようにするために必要なんだそうな。v8エンジンであると説明があるけど、なんだかわからん。Google製のJavaScriptエンジンだって。そうすか。
 このあたりの話で何度か見たことのあるNode.jsは、サーバー側で動作するJavaScript環境を提供するみたい。一応メモ。同じJavaScriptでどうしてサーバーとクライアントが別なのかようわからんけど、今はそういうもんだとしておこう。
 で、coffeeとsassをのファイルをそれぞれ作りアクセス確認する。
# shout.js.coffee
alert("Hellooooooooooo!!!")
shout = ->
 上のcoffeeで書かれたものがブラウザに渡されたときには下記のようなjs書式に変換されている。
(function() {
var shout; shout = function() {
return alert("Hellooooooooooo!!!");
}; }).call(this);
  sassの方も同様。
 でも、CSSはぼんやりわかってもJavaScriptなんてなにも知らないんですけど。
 あ、でもここで重要な説明が。Sprocketsがファイル内容を変換して適切な形にしてレスポンスすること、これがAsset Pipelineなんだって!やっと!そうすか!
 何の説明かわからずに話を聞いているのって、全然頭に入らない。頭が整理されない。辛い。からい、じゃないすよ。

依存性の管理

依存関係のあるアセットファイルでは、先に読み込んでおくべきファイルを下記のように指定することができます。依存関係を管理する独自の構文のことをディレクティブと呼ぶ。
//= require jquery #オプションはディレクティブと引数。
サポートされているディレクティブについては、//= require jquery参照する。

マニフェストファイル

アクセスの度にファイルからいろいろなファイルが呼び出されると効率が悪いので、jsやCSSを事前に1ファイルに渡して提供している。この仲介をしているのがマニフェストファイル。
 Railsでアプリケーションを新規作成した場合にデフォルトで用意されるマニフェストファイルは以下の2点。
app/assets/javascripts/application.js
app/assets/stylesheets/application.css
中にはこのファイル自分自身と、同じディレクトリにあるファイルが自動で読み込まれる設定が書かれている。

Railsにおけるdevelopment環境とproduction環境の違い

production環境ではパフォーマンス重視、でも開発環境では管理しやすさが大事。
 ヘルパーメソッド(stylesheet_link_tag等)を利用すると、ディレクティブで指定した順にファイルが読み込まれる。(ちなみにCSSは後から読み込まれた設定が有効。)
 開発環境ではこの読み込まれた各リンクが個別にhtmlに書き出され、production環境では1ファイルにまとまって読み込まれる。
 強制的にproduction環境を再現する場合は、下記をfalseに変更する。
#config/environments/development.rb
config.assets.debug = true # ->false

マニフェストファイルのプリコンパイル

Sprocketsでは、アクセスごとにコンパイルを行います。でもこれは非効率的なため、Railsにはプリコンパイルという仕組みが用意されている。事前にコンパイルして静的ファイルとして用意して高速なレスポンスを実現します。
 プリコンパイルは下記で実行できる。
.bin/rake assets:precompile
デプロイするときはあれやこれや注意しなさいと書いてあるけど、まだよくわからないのでそのときにp103を見返そう。
 その他、必要に応じて機能ごとにマニフェストファイルを作ったり、ファイルを縮小化して読み込み効率を上げるminifyとかってことが書かれている。

 まずいぞ。まずいぞ。こんなペースだと、演習しながらで1年かかっちゃうぞ。

2014年6月27日金曜日

2-5 MVCについてのまとめ

Model

  • ActiveRecordの基本的な操作
  • バリデーション
  • コールバック

Controller

  • ModelとViewをつなぐ働き
  • リクエストオブジェクト
  • アクションコールバック
  • 脆弱性への対処

View

  • 受け取ったModelを表示する
  • テンプレートエンジン
  • ヘルパー
  • いろいろなフォーマットでの表示

注意点

  • アプリケーションの主要なロジックはModelに書くべき
    • コードが整理される
    • テストがしやすい
  • ViewとControllerにはそこでしかできないことだけを書く
  • 上記を守らないとレイヤーの依存関係が破壊され、メンテナンス性も良くない
  • Modelが肥大化(Fat Model)するが、9章でアドバイスをする

 んーと、リクエストオブジェクトってなんだっけ。ひとことも出てきてない気がするんだけど…。おれがバカなの?
 
参考:

2-4 ビューの役割

レンダリングの仕組み

HTMLによるUIだったり、APIの返り値だったり。簡単なビューはrenderメソッドで描かれる。

テンプレートの検索

 テキスト通りに画面表示がされず、しばらくハマってしまった。ちくしょう。
 htmlファイルと自分が考えているものは実際はerbファイルで、パラメータによりそれぞれhtmlが生成されるのでテンプレートファイルと言うみたい。結果的にはhtmlファイルと同じ。同じというか最後にhtmlになる。
 URL問い合わせ→routes.rb→アクション→テンプレートという順で何を画面に表示するか決定する。

renderを省略した場合

 アクションの定義として、render :showと表現していたが、コントローラ、アクション名、ビューのファイル名が規約通りに決められていれば、renderは省略できる。
 何をしたらどんな恩恵が受けられるかわかっていないから、この素人を混乱させるような気がする。早く覚えろよってことなんでしょうけど。優しいのか優しくないのかよくわからない。

コンテンツのタイプによって表示を出し分ける

 コントローラのアクション定義として下記のようなことを書けば拡張子によって応答させるファイルが使い分けられるらしい。
 例として出ているCSVファイルを書き出す方法はどこかで使えそう。例えば、/books/1.csvへ問い合わせれば、csvファイルのダウンロードという形で応答がある。
def show
@book = Book.find(params[:id])
respond_to do |format|
format.html
format.csv
format.json
end
end
 元々はコントローラ名/アクション名.フォーマット.エンジンという規約てテンプレートを探しにいく。
 例外的に処理をさせたい場合は下記のようrenderメソッドのオプションを使う。p78参照。
format.xml { render xml: @book }
 リダイレクトもできる。
redirect_to books_path
redirect_to books_path, status: :found #ステータスコードやシンボルも渡せる

partialテンプレートとlayout

 テンプレートは、基本的にまずviews/layouts/application.html.erbを読み、yieldに街頭アクションテンプレート(show.html.erbとか)が埋め込まれ、必要なところでpartialテンプレートを読む。
 partialテンプレートはlayouts内に配置するが、sharedフォルダを作って入れておくのが一般的?ファイル名はpartial以外と混同しないように、先頭にアンダースコアを入れる決まり。
<%= render partial: 'form' %>
 formがファイル名になるが、コード上はアンダースコアを入れない。実ファイル名には入れる。_form.html.erbとか。

variantsによるテンプレートの切り替え

 Rails4.1からは接続端末の種別に合わせたテンプレートを応答させることができる。
 以下はiPhoneから接続するとvariantに:mobile値が返され、show.html+mobile.erbを応答ファイルとして使用します。
class ApplicationController < ActionController::Base
before_action :detect_mobile_variant
  private
  def detect_mobile_variant
  request.variant = :mobile if request.user_agent =~ /iPhone/

end

ヘルパーの利用

 ビューを表示するときに、長い数値を3桁区切りにするとか、ちょっとした変換、一手間が必要なときは組み込みヘルパーを使えってよ。
 パラメータからURLを生成するurl_for、フォーム作成form_tag、フォーム操作form_for等。headで宣言に使われていたstylesheet_link_tagやjavascript_include_tagもヘルパーなんですって。やっと謎が解けた。
<%= url_for(controller: :books, action: :show, id: 1) %>
#=> /books/1
これだと、ある程度ルーティングが変更されても、ここが吸収してくれていちいちメンテナンスしなくてすみそう。
 オブジェクトの後に続いてないし、これはクラスメソッドの関数版と思えばいいのかな。予約関数というか。古い脳の持ち主としては、こういう書式だとなんかしっくりきますね。
 予約されているヘルパーで間に合わない場合は、独自のヘルパーを作成することもできる。app/helpers/application_helper.rbへモジュールを書き足せば、アプリケーション内のビューから利用できるようになる。
 コントローラごとに使用する場合には、books_helper.rbとコントローラを利用したファイル名にすればよい、と。また規約ですか。
 えらい人に、また規約ですね、と聞いたらこれは規約じゃないとか言われることもあって、その線引きがわからない。全体を理解して初めて線引きがわかるというのもどうかと思う。

エスケープ処理

クロスサイトスクリプティング(XSS)という攻撃を回避するためにエスケープという処理、対策をRailsでは実装している。
 エスケープされると困る場合には、以下のようにrawを使って回避できる。
<%= raw "<script>alert('sample');</script>" %>
多重エスケープで表示が崩れてしまう場合にrawが使えるようなことが書いてあるけど、ちょっとまだよくわからない。今はXSSにちょっとした対策をしていることだけ覚えておこう。

APIサーバにとってのビューについて

しばらく、書いていて意味の分からないことが続いている。ちょっと頑張ります。
 特にスマートフォンでは、スマホアプリからサーバの情報を持ってくる場合があったりして、RailsアプリケーションがHTTP APIとして振る舞う必要が求められるケースが多くなってきている。入力していてよくわからない。死ねる。んーと、WEBサーバーって読み替えちゃっていいのかな…。
 例えとしてJSONが出てきたけど、これもわからない。わからないけど、jbuilderというのがそのアプリケーションらしい。Gemfileにはすでに書かれていた。
 jbuilderの場合には、app/view/books/show.jbuilder.jsonというファイルをテンプレートとして使う。わからないけど作った。
 ん、作ったけどbooks/1.jsonでアクセスできず。Template is Missingと言われてしまっている。ルーティングもアクションも問題無さそうだけど…。
 ・・・見本としてscaffoldしたときのデフォルトファイルを見てみると、show.jbuilder.jsonじゃなくてshow.json.jbuilderだった!(初版 p89)えー。テキストのミスかい?それであたしから半日くらい奪ったのかい?あんまりわからなくてTwitterやYoutubeやYahoo知恵袋のアホな質問をいくつも見てしまったよ!やっと進める。でもなにやっていたか忘れちゃった。
 というか、scaffoldってすごいね。バカの一つ覚えでscaffold〜チューニングという流れで自分のやりたいような簡単なことは全部できそうな気がするな。
 ちなみに上で大変な目にあってできたことは以下の通り、たったこれだけ。
json.extract! @book, :id, :name, :price, :created_at #show.json.jbuilder
{"id":1,"name":"Book 1","price":1000,"created_at":"2014-06-25T07:04:24.117Z"} #画面出力
なんかどっと疲れが出た。なにも食べてないからたい焼き食べる。たい焼き食べた後、疲れてウトウトしてしまった。
 使ったサンプルを一応載せるけど、JSONについてのうまい説明が無くてアホな私にはどんな時に使うべきかがピンとこなかった。とりあえず存在だけ忘れないようにしておこう。スマホが相手のときには必要になるんだろうか。
json.extract! @book, :price
json.name_with_id "#{@book.id} - #{@book.name}"
json.publisher do
  json.name @book.publisher.name
  json.address @book.publisher.address
end
unless @book.high_price?
  json.low_price true
end
 high_priceメソッドが未定義だと怒られてしまったけど、2-2でファイル内に打ち込んでいなかった模様。

2014年6月26日木曜日

2-3 コントローラ

 まずはコントローラ作成。
$ rails g controller books
booksの部分、コントローラの性質によって複数形にするかは常識的に判断とえらい人が言っていたがイマイチピンとこない。モデル持つような場合、基本的に複数になるとか、そんな感じかな。
 コントローラの設定としては、app/controllers/books_controller.rb。ここにアクションを書く。問い合わせに対してどんな回答をするかってのをアクションとして定義する。
def show
@book = Book.find(params[:id])
respond_to do |format|
format.html
format.csv
format.json
end
end
 /books/1とかでアクセスが来たときには、この1がparams[:id]として処理される。レコードごとのページの表示とか、かな。
 respond_to doの部分では、ユーザーのリクエストに応じて3種類のビューのレンダリングができるようになっています。

アクションコールバック

 モデルと同じように、アクションにもコールバックがある。
  before_action :set_book, only: [:show, :edit, :update, :destroy]
  private
  def set_book
  @book = Book.find(params[:id])
  end
 なんでprivateなの?とりあえずprivateにすると、自クラスかサブクラスからしか呼び出せないみたい。
 親クラスで定義したアクションコールバックをskip_before_actionのようなskipメソッドもある。

ルーティングとresources

 resourcesをネストすると、親子関係をルーティングで表すことができる。/publisher/:publisher_id/books/:idとか。
 一人のユーザーから見て一つしか存在しないリソースの場合には、resourceでルーティングを定義することも可能。この場合はindexは作られず、:idによる絞り込みも設定されない。
 resource(s)で、:onlyを使うと、特定のアクションのみについてルーティングを設定することができる。下記ではshow/edit/updateだけ定義される。
resources :profile, only: %i{show edit update}

 例外処理

 一般のWEBサーバーのHTTPステータスコードとは別に、Rails独自のものがある。p71参照。
 クラスメソッドrescue_fromと合わせると特定の例外に特定の処理をひも付けしやすい。多くの場合、ApplicationControllerに宣言する。
class LoginFailed < StandardError
end
class ApplicationCntroller < action_controller::Base
  rescue_from loginFailed, with: :login_failed
  def login_failed
    render templete: 'shared/login_failed', status: 401
  end
end

StrongParameter 

 Rails4で実装されたStrongParameterは脆弱性に対抗する手段の一つ。
 あー、だめだ。眠い。p73あたりはまともなサイト作るときにもう一度読み直そう。
 scaffoldで生成されるコードにはStrongParametersを使うようになっているそうだし。

2-2 モデル

 いきなり何の説明も無くActiveRecordという単語が出てきた。索引見ても、これが最初に出てきたページだ。なんだよ。いじめかよ。 とりあえず、言われた通りモデルを作る。書籍を管理するカラムを同時に指定しています。えっと、書籍名と発売日と価格とページ数ですか。
$ rails g model Book name:string published_on:date price:integer number_of_page:integer
  本にうるさい人間としては、正直ISBN的なユニークな記号が無くては管理に行き詰まりそうな気がして心配です。まぁ、そんなことはどうでもいいです。
 /app/models/book.rbがモデルで、/db/migrate/〜がテーブル生成用のマイグレーションファイル。
 マイグレーションファイルについて、「ActiveRecord::MigrationのDSLで記述したものです」と書かれているけど、どちらの意味も全くわからない。解説も無い。

参考:
5. クラスとモジュール
第1回 DSLとは?

 要するにクラスMigrationがモジュールActiveRecordの中でネスト(入れ子)になっているということでいいのでしょうかね。いいのでしょうかと言っても、その説明自体の具体的な経験が無くてイメージわかず。言葉で覚えただけ。そのうちわかりそうな気はする。

 マイグレーションしてbook.rbを見るも、クラスが定義されているだけで、中身は空っぽ。
 ’<’はクラスの継承で、そのうち説明してくれるでしょう。つーか、Rubyを知らずにこの本読んじゃいけないんじゃなかろうか。ま、いいか。
$ cat app/models/book.rb
class Book < ActiveRecord::Base
end
でも、コンソールで確認するとフィールドが定義されていてdbの格好になっている。もちろんデータは何もありません。
$ rails c
Loading development environment (Rails 4.1.1)
irb(main):001:0> Book.new
=> #<Book id: nil, name: nil, published_on: nil, price: nil, number_of_page: nil, created_at: nil, updated_at: nil>
irb(main):002:0> Book
=> Book(id: integer, name: string, published_on: date, price: integer, number_of_page: integer, created_at: datetime, updated_at: datetime)
irb(main):003:0> Book.all
  Book Load (0.2ms)  SELECT "books".* FROM "books"
=> #<ActiveRecord::Relation []> 
あ、ここで解説。
 ActiveRecordはdbと接続してレコードとエンティティを結ぶ。これはモデルクラスに何も記述しなくてもテーブルのカラム情報を取得してモデルのフィールド情報に自動反映するような動作を実現する。また、接続情報を隠蔽する。
 もう一つ、バリデーションやコールバック等のビジネスロジックを実行する役割を持つ。実際にはこの動作はモジュールActiveModelが担っている。まずは基本的なバリデーションやコールバックを覚えればそれで良い。
 全くわからない。言葉同士の関係性はなんとなくわかるけど、その他は全く。でも体で覚えられるポイントな気がするので、気に留めるだけにして先に進む。
動詞 : 具体的な内容 : ActiveRecordの対応するメソッド
Create : レコードを作る : Book.create / Book#save
Read : レコードを参照する : Book.find / Book.all
Update : レコードを更新する : Book#save / Book#update_attributes
Delete : レコードを削除する : Book#delete / Book#destroy
Readは読み出しだけでなので参照系、その他はデータの書き変わるので更新系と分類される。

 今後実際にデータを入力して検証することも出てくるそうで、コンソールで本のデータを少し入力しておく。
$ rails c
Loading development environment (Rails 4.1.1)
irb(main):001:0> (1..5).each do |i|
irb(main):002:1* Book.create(name: "Book #{i}", published_on: i.months.ago, price: (i * 1000))
irb(main):003:1> end #データ作成
   (0.1ms)  begin transaction
  SQL (0.6ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-25 07:04:24.117114"], ["name", "Book 1"], ["price", 1000], ["published_on", "2014-05-25"], ["updated_at", "2014-06-25 07:04:24.117114"]]
   (0.7ms)  commit transaction
   (0.1ms)  begin transaction
  SQL (0.2ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-25 07:04:24.124550"], ["name", "Book 2"], ["price", 2000], ["published_on", "2014-04-25"], ["updated_at", "2014-06-25 07:04:24.124550"]]
   (0.7ms)  commit transaction
   (0.1ms)  begin transaction
  SQL (0.2ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-25 07:04:24.127138"], ["name", "Book 3"], ["price", 3000], ["published_on", "2014-03-25"], ["updated_at", "2014-06-25 07:04:24.127138"]]
   (0.6ms)  commit transaction
   (0.0ms)  begin transaction
  SQL (0.2ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-25 07:04:24.129217"], ["name", "Book 4"], ["price", 4000], ["published_on", "2014-02-25"], ["updated_at", "2014-06-25 07:04:24.129217"]]
   (0.7ms)  commit transaction
   (0.0ms)  begin transaction
  SQL (0.2ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-25 07:04:24.131291"], ["name", "Book 5"], ["price", 5000], ["published_on", "2014-01-25"], ["updated_at", "2014-06-25 07:04:24.131291"]]
   (0.6ms)  commit transaction
=> 1..5
irb(main):004:0> Book.find(1) #id検索
  Book Load (0.2ms)  SELECT  "books".* FROM "books"  WHERE "books"."id" = ? LIMIT 1  [["id", 1]]
=> #<Book id: 1, name: "Book 1", published_on: "2014-05-25", price: 1000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">
irb(main):005:0> Book.find_by(name: "Book 3") #書籍名、発売日で検索
  Book Load (0.2ms)  SELECT  "books".* FROM "books"  WHERE "books"."name" = 'Book 3' LIMIT 1
=> #<Book id: 3, name: "Book 3", published_on: "2014-03-25", price: 3000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">
irb(main):006:0> Book.where("price > ?", 2000) #複数レコード検索
  Book Load (0.2ms)  SELECT "books".* FROM "books"  WHERE (price > 2000)
=> #<ActiveRecord::Relation [#<Book id: 3, name: "Book 3", published_on: "2014-03-25", price: 3000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">, #<Book id: 4, name: "Book 4", published_on: "2014-02-25", price: 4000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">, #<Book id: 5, name: "Book 5", published_on: "2014-01-25", price: 5000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">]>
irb(main):007:0> Book.where("price > ?", 2000).limit(3).order(:name) #メソッドをチェーンさせることもできる(Query Interfaceという機能)
  Book Load (0.3ms)  SELECT  "books".* FROM "books"  WHERE (price > 2000)  ORDER BY "books"."name" ASC LIMIT 3
=> #<ActiveRecord::Relation [#<Book id: 3, name: "Book 3", published_on: "2014-03-25", price: 3000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">, #<Book id: 4, name: "Book 4", published_on: "2014-02-25", price: 4000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">, #<Book id: 5, name: "Book 5", published_on: "2014-01-25", price: 5000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-25 07:04:24">]>
SQLに使えるActiveRecordのメソッドは、select / where / limit / offset / order / group / joins / includes / not がある。SQLの話だし、ここではメソッド名だけ。でも実際にはすごく使うんだろうな。使いながら覚える方向で。

 ActiveRecord::Relationクラスは、ActiveRecordのQuery Interfaceの操作結果をオブジェクトとしたもの。メソッドがチェーンされるごとにdbにアクセスするのではなく、チェーンした条件で問い合わせをするようなイメージかな。SQLの実行結果を配列の感覚で扱える、とか。よくわからん。

 突然scopeの話。よく利用する検索結果をひとまとめにしたもの、だそう。再利用性と可読性が向上してイイネということらしいです。
 /app/medel内で定義する。今回は/app/model/book.rb。
class Book < ActiveRecord::Base
  scope :costly, -> { where("price > ?", 3000 )}
  scope :written_about, ->(theme) { where("name like ?", "%#{theme}%") }
end
これで、Book.costlyでprice>3000の条件が抽出できる、と。
 複数のscopeをand処理することもできる。Book.costly.written_about("java")なら、書名にjavaとつく3千円より高い書籍を探すことができる。:written_aboutのように、パラメータをとるスコープも定義できる。
 でもググっていたらこういう書き方困るんだよねー、みたいな情報もあるので一応リンクだけ張っておきます。

参考:
ActiveRecord4でこんなSQLクエリどう書くの? Arel編

 デフォルトでどのスコープにも適用したいスコープについてはdefault_scopeで定義できる。忘れていると思わぬ挙動になるので注意。
default_scope -> { order("published_on desc") }
モデル同士のリレーションについて。Bookに続いてPublisherとAutherというモデルを作成。これらを関連づけるために下記でマイグレーションを作成すると言うんだけど、どこから出てきたんだ。丸暗記?
rails g migration AddPublisherIdToBooks publisher:references
これでBookにはPublisherモデルへの参照が追加された。この過程でBookにはpublisher_idというフィールドが追加されている。
 ところで、あるbookには一意にpublisherが決まる状態を/app/models内に記述しておくと、出版社と本がひもづいてお互いにメソッドして利用できるようになるようです。
 Publisher側は以下の通り。Bookについても同様にbelongs_to :publisherを書いておきます。
class Publisher < ActiveRecord::Base
has_many :books
end
下記がコンソールで確認した内容。
irb(main):015:0> publisher = Publisher.create name: 'gihyo', address: 'ichigaya'
   (0.1ms)  begin transaction
  SQL (0.4ms)  INSERT INTO "publishers" ("address", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?)  [["address", "ichigaya"], ["created_at", "2014-06-26 01:23:58.851325"], ["name", "gihyo"], ["updated_at", "2014-06-26 01:23:58.851325"]]
   (2.9ms)  commit transaction
=> #<Publisher id: 2, name: "gihyo", address: "ichigaya", created_at: "2014-06-26 01:23:58", updated_at: "2014-06-26 01:23:58">
irb(main):016:0> publisher.books << Book.find(1)                                  Book Load (0.2ms)  SELECT  "books".* FROM "books"  WHERE "books"."id" = ? LIMIT 1  [["id", 1]]
   (0.1ms)  begin transaction
  SQL (0.3ms)  UPDATE "books" SET "publisher_id" = ?, "updated_at" = ? WHERE "books"."id" = 1  [["publisher_id", 2], ["updated_at", "2014-06-26 01:24:10.115361"]]
   (2.9ms)  commit transaction
  Book Load (0.1ms)  SELECT "books".* FROM "books"  WHERE "books"."publisher_id" = ?  [["publisher_id", 2]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Book id: 1, name: "Book 1", published_on: "2014-05-25", price: 1000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-26 01:24:10", publisher_id: 2>]>
irb(main):017:0> publisher.books.to_a
=> [#<Book id: 1, name: "Book 1", published_on: "2014-05-25", price: 1000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-26 01:24:10", publisher_id: 2>]
irb(main):018:0> book = Book.find(1)
  Book Load (0.1ms)  SELECT  "books".* FROM "books"  WHERE "books"."id" = ? LIMIT 1  [["id", 1]]
=> #<Book id: 1, name: "Book 1", published_on: "2014-05-25", price: 1000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-26 01:24:10", publisher_id: 2>
irb(main):019:0> book
=> #<Book id: 1, name: "Book 1", published_on: "2014-05-25", price: 1000, number_of_page: nil, created_at: "2014-06-25 07:04:24", updated_at: "2014-06-26 01:24:10", publisher_id: 2>
irb(main):020:0> book.publisher
  Publisher Load (0.1ms)  SELECT  "publishers".* FROM "publishers"  WHERE "publishers"."id" = ? LIMIT 1  [["id", 2]]
=> #<Publisher id: 2, name: "gihyo", address: "ichigaya", created_at: "2014-06-26 01:23:58", updated_at: "2014-06-26 01:23:58">
irb(main):021:0> book.publisher.name
=> "gihyo"
もう、頭が大混乱しています。
 上の例のように1対多ではなく、1対1で決まる場合には、has_oneというクラスメソッドが用意されているそうです。
 本と著者のように、多対多の関係もあります。この場合は一旦中間モデルを作成します。します、とか書いてますが全然わかっていません。
rails g model BookAuther book:references auther:references
そしてAutherに下記を追加。
class Auther < ActiveRecord::Base
has_many :book_authers
has_many :books, through: :book_authers
end 
どうしてBookAutherを挟まないといけないのか。よくわからない。わかりにくいと感じるけど、この本には中間テーブルの作成やこれをキーにしたデータの取得がActiveRecordのおかげで楽になっていると書かれている。そうなんだ…。
 Bookにも上に習って逆向きで宣言する。
 コンソールでの確認は面倒になってきたので、というか時間がないので、パス。こういうのがいけないんだよね。わかってはいるんだけどね…。

ActiveRecordを利用したデータの保存

 突然ですが、記事があまりに長くなってきたのでたまに見出しを入れることにします。
Book.create name: "Rails Book", published_on: 2.months.ago, price: 2980
上記は、下記に分解して入力したものと同じ意味を持ちます。
irb(main):002:0> book = Book.new
=> #<Book id: nil, name: nil, published_on: nil, price: nil, number_of_page: nil, created_at: nil, updated_at: nil, publisher_id: nil>
irb(main):003:0> book.name = "Rails Book"
=> "Rails Book"
irb(main):004:0> book.published_on = 2.months.ago
=> Sat, 26 Apr 2014 01:52:05 UTC +00:00
irb(main):005:0> book.price = 2980
=> 2980
irb(main):006:0> book.save
   (0.1ms)  begin transaction
  SQL (0.8ms)  INSERT INTO "books" ("created_at", "name", "price", "published_on", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-06-26 01:52:24.327140"], ["name", "Rails Book"], ["price", 2980], ["published_on", "2014-04-26"], ["updated_at", "2014-06-26 01:52:24.327140"]]
   (2.4ms)  commit transaction
=> true 
  データを更新する場合は、必要なレコードをfind等で取得し、特定のフィールドを更新してsaveするだけ。削除は特定のレコードにdestroyメソッドを呼び出すだけでいい。
 あ、書いててわかった。レコードってあるモデルのあるidにひもづいたデータをひとまとめにした単位か。今更。フィールドはカラムとほぼ同意みたい。エクセルで言う列。この本の中でもフィールドとカラムという言葉が出てきてややこしい。厳密には違うのかもしれないけど。

バリデーション

データの入力ルール。あるフィールドにデータが入るときに、適切であるデータ形式であるかチェックする。
 books.rbに以下を追記する。
  validates :name, presence:true #入力必須
  validates :name, length: { maximum: 15 } #15字以内
  validates :price, numericality: { greater_than_or_equal_to: 0} #0以上の数値
条件を満たしていないと、レコードの保存に失敗する。save時にfalseとなる。
 errorsメソッドでエラーの内容を確認することができる。
irb(main):005:0> book.errors
=> #<ActiveModel::Errors:0x007fcea720e950 @base=#<Book id: nil, name: "asdfajsdfaksfsladfalsdfjasldj", published_on: nil, price: nil, number_of_page: nil, created_at: nil, updated_at: nil, publisher_id: nil>, @messages={:name=>["is too long (maximum is 15 characters)"], :price=>["is not a number"]}>
saveせずにバリデーションだけを行う場合は、valid?が使える。book.valid?でtrue/falseの判定ができ、falseの場合はerrorsインスタンスにエラーが書き出される。便利そう。
 バリデーションの一覧がp57にあって、きっと今後よう使うことになりそう。値の存在、ユニークかどうか、数値かどうか等々、いろいろあるようです。
 あれ、と思ったら下記のように式とエラーを宣言して自分で条件が作れるんだって。そうすか。
validates do |book|
  if book.name.include?("exercise")
    book.errors[:name] << "I don't like exercise."
  end
end

コールバック

レコード作成から保存までの間に任意の処理を呼び出すことをコールバックという。
 レコード処理の前後処理や、保存後に必ず行う処理等、コールバックを利用することで実行漏れが防げる。"cat"が含まれていたら"lovely cat"におきかえる、とか。あー、わかりやすい。珍しい。
before_validation do |look|
  book.name = book.name.gsub(/Cat/) do |matched|
    "lovely #{matched}"
  end
end
before_validationはバリデーションの前にチェックするよってことかな。たまに出てくる"|"の意味がわからないけど、形式的なものなんだろうか。gsubは正規表現でマッチしたものを置換するんですって。
 メソッドを使うと下のように書ける、ときたけど、オブジェクト思考に慣れていないからかまだ違和感を感じる。
before_validation :add_lovely_to_cat
def add_lovely_to_cat
  book.name = book.name.gsub(/Cat/) do |matched|
    "lovely #{matched}"
  end
end
以下はレコード削除時にログに書き出す方法。
  after_destroy do |book|
  Rails.logger.info "Book is deleted: #{book.attributes.inspect}"
  end
確かにlog/development.logにBook is deleted:〜の表示が出ました。
 コールバックを行うタイミングはいろいろ用意されているようです。before_validationやらafter_saveやら、いろいろ。p59参照。

コールバックの起動に条件付けをする

def high_price?
  price >= 5000
end
after_destroy :if => :high_price? do |book|
  Rails.logger.warn "Book with high price is deleted: #{book.attributes.inspect}"
  Rails.logger.warn "Please check!"
end
 5千円以上の本のレコードを削除すると、メッセージを表示する。
 :ifや:unlessではProcオブジェクトも使えるという説明があるんだけど、procって?ブロックをオブジェクト化したもの。ブロックはメソッドの引数となるdo~endや{~}で囲われたかたまり。よくわかんないね。いいよ、もう。

参考:

 Rails4.1で追加されたActiveRecordの機能として、enum型(列挙型)という変数形式が追加されている。p61参照。
 コード上ではわかりやすい定数として扱えて、db上では数値として保存されるため、dbの空間効率がよくなる。

2014年6月25日水曜日

2-1 MVCアーキテクチャ

 MVCについて。イメージはつかめている。データベースの操作のことをModelと呼ぶことには、慣れていないせいか変な感じがします。
 Viewはサーバーへの問い合わせに対するhtmlによる視覚的な応答。ControllerはMVCをつなぐ司令塔ってところでしょうか。

参考:
Ruby on Rails究極指南:第1回 Instant Railsで始めるWindows環境のRails (1/2)

 唐突ですが、書籍管理アプリを作るそうです。
 以前のディレクトリから抜けて、新たにプロジェクトを作成します。
$ rails new book_admin

1-4 scaffoldを使ってRailsでの開発を体験しよう

 scaffoldはCRUD(Create/Read/Update/Delete)を簡単に実現させることができる。詳しくは2章だって。
MVCそれぞれのファイルとコードの生成、データベースのテーブル定義ファイルの生成をコマンド一つで終わらせてくれる。
 すげーな。自分の作りたいテキトーなサイトなんて、これベースでいけちゃうんじゃないの。
rails generate scaffold task content:text
はい、作れた。/appの中にMVCそれぞれの最低限必要なファイルが 作られたようです。
 taskのところがコントローラ名。その後はその要素。カラム名:変数タイプ、という書式。

 /db/migrate内には、データベースのテーブルを作成するために必要な情報が書き記された長い名前のファイルが作られています。
 その後、この生成されたファイルを基にデータベースの作成とテーブルへの変更を行う。
rake db:create
rake db:migrate
プライマリーキーidとタイプスタンプt.timestampsは自動で作られる。

 一応、データベースソフトsqlite3で、どのような命令が実行されたか確認してみる。
$ sqlite3 db/development.sqlite3 ".schema tasks"
CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "created_at" datetime, "updated_at" datetime);
おっと、なんかもう怪しくなってきた。眠いし。

 migrationの状態を確認することができる。statusがupならmigration済み。downは未適用。
$ rake db:migrate:status
database: /Users/moc720814/work/todo/db/development.sqlite3
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20140625033406  Create tasks
確認がいくつか入りましたが、これでscaffoldによって簡単なサイトができました。アクセスは、http://localhost:3000/tasksで可能です。

 どのURLがどのページとリンクしているのか、といったルーティング情報については、下記のように特定のURLにアクセスするか、ターミナル上でコマンドを打ちます。
http://localhost:3000/rails/info/routes #このURLにルーティング情報が表示される
$ rake routes
   Prefix Verb   URI Pattern               Controller#Action
    tasks GET    /tasks(.:format)          tasks#index
          POST   /tasks(.:format)          tasks#create
 new_task GET    /tasks/new(.:format)      tasks#new
edit_task GET    /tasks/:id/edit(.:format) tasks#edit
     task GET    /tasks/:id(.:format)      tasks#show
          PATCH  /tasks/:id(.:format)      tasks#update
          PUT    /tasks/:id(.:format)      tasks#update
          DELETE /tasks/:id(.:format)      tasks#destroy
  例えば、黄色いラインについては、HTTPのPOSTメソッドで/tasksへリクエストするとtasksコントローラのcreateメソッドが実行される、という意味。メソッドって言葉にまだ慣れないな…。
 Prefixについては、htmlを生成するerbファイル(Embedded Ruby)で/tasks/editをedit_task_path等と表現できるようになるようだけど、イマイチ効能がよくわからない。
 また、このルーティングの設定はどこでやってんの、という疑問については、/config/routes.rbを見ればいいのですが、見てもよくわからない。
Rails.application.routes.draw do
  resources :tasks
end
コメントアウトされている行を抜かせばこの3行しか無い。要はresourcesメソッドに:tasksを渡せばその辺はCRUDが実現できるようにうまくやっといてあげる、ということらしいです。
 ところでこのコロンは何だい?シンボル?理解し難いね…。

参考:[Rails]Rubyのカベ-シンボルって何だ?

 HTTPメソッドのGET/POST/PUT/DELETEがshow/create/update/destroyアクションに対応していて、RESTfulな考え方をベースに実現されている。逆に言えばRESTfulを意識して開発するとRailsの恩恵を受けやすく、わかりやすい構造になる、と。わかりにくいよ!


1-3 Railsをはじめよう!!

gem install rails -v 4.1.1 #Railsのインストール
rails -v #Railsのバージョン確認
rails _4.0.5_ -v #複数のバージョンがある場合は指定できる
rails new todo #プロジェクトのひな形を作る
 プロジェクトのディレクトリ構成についてはp29を参照。
 とりあえずapp、config、ルートディレクトリあたりを覗いておけばいいのかな。基本的にはMVC(Model/View/Controller)というRailsのアーキテクチャに沿った構造になっているようです。

参考:

 作成されたプロジェクトディレクトリtodoに移って、動作確認用のWEBサーバー(WEBrick)を起動してみる。
./bin/rails server
rails s #省略できる
 http://localhost:3000に接続すると、デフォルトのページが確認できる。
 よく使うオプションgenerateも省略でき、rails g 〜と書ける。

 あー、もう疲れた。まだ数十分しか経ってないのに。

1-2 Railsの思想

 Railsは以下の4つの思想を強く打ち出しているんだと。
CoC (Convention over Configuration) : 設定より規約に従う
DRY (Don't Repeat Yourself) : 同じコードを何度も書かない
REST (Representational State Transfer) : URIで全てのリソースを操作する手段を提供する
自動テスト : テストをしながらコードを書く
 こういった思想の基でアプリケーションを作成することを、レールに乗ると表現する。って、そこまで決められているともう宗教的で気持ち悪いけど、まぁいいか。

1-1 Railsを使う前に

 パッケージ管理を行うgemや、Linuxで言うところのビルドツールmakeにあたるrakeについての解説。
 Rakefileをいじって実行させる例が載っている。そのうち使うかも、と。p22

 実際のgemの管理はBundler(bundleコマンド)を使う。
bundle install : Gemfileに書かれたgemをインストールする
bundle update : インストール済みgemの更新
bundle list : インストール済みgemの一覧表示
bundle init : Gemfileを生成する(gemパッケージのサーバー)
bundle exec : bundlerでインストールされたgemパッケージを実行する
bundle installでは、Gemfileの内容に従ってパッケージがインストールされる。
 Gemfileへの書式は下記の通り。
gem 'rails'
gem 'rails', '4.1.1' #バージョン指定
基本的に、インストールされたgemパッケージを実行するには、下記のような書式が必要となる。
bundle exec [命令] [オプション]
やばい、このペースだとなかなか進まないぞw 
 でも頑張ろう。ちゃちゃっとおさらいしてしまおう。

パーフェクト Ruby on Rails

 パーフェクト Ruby on Railsという本に沿ってRailsをやり直します。やっぱり紙のテキストが無いと世代的にダメなのかもしれない。ちょっと読んでも理解しやすそうだったので、こちらで再スタートしてみます。
 場当たり的なメモではなく、すんなり理解できたところもやった題目だけでも記して順を追って記録していきたいと思います。かいつまんで記録しても後から見て理解しづらい。

 作ってしまった、** PC - Ruby on Railsというカテゴリーは適当にTipsとかのメモに使うことにします。

 さて、やろうやろう。

2014年6月24日火曜日

リモートのトピックブランチをpullする方法

 リモートにあるトピックブランチをpullする場合は、下記を実行する。
$ git branch new-branch origin/new-branch
$ git checkout -b new-branch origin/new-branch #ブランチ作成後に移動
参考:
Git で新しいリモートブランチをローカルに持ってくるときに git pull してはいけない理由

2014年6月23日月曜日

デフォルトレイアウトapplication.html.erbを使わない

 コントローラによりapplication.html.erbを適用しない、あるいは他のレイアウトファイルを使う場合にはコントローラやアクションに対して下記のように定義すれば良いみたい。
class MusicsController < ApplicationController
  layout 'basic' #コントローラ全体に対する設定
  def show
    render :layout => 'compact' #アクションに対する設定
  end
end
ここへきて全く頭に入らない。ふんわりとしか理解できない。難しい。
 htmlで書かれたサイトをrails/hamlでリライトする練習をしていますが、全然手が動かない。思考停止。やった事が再現できない。あうふ。

参考:
コントローラやアクション毎に使用するレイアウトを切り替える
Ruby on Railsでapplication.html.erbを適用したくないページの設定

spring バージョンに関するエラー

There is a version mismatch between the spring client and the server.
You should restart the server and make sure to use the same version.
CLIENT: 1.1.2, SERVER: 1.1.3
上記エラーが出て、なんだか原因はよくわからないですが、回避するにはとりあえずspringを再起動すべしとのこと。
spring stop
spring rspec
参考:
springのバージョンでハマったら
Rails – RSpecの設定と使い方

ユーザー認証

 Railsチュートリアルの6章、やっている雰囲気はつかめたしRails3.1からはhas_secure_password、validates、has_secure_passwordメソッド等のおかげでこの点が非常に簡単に実装できるという事はわかったんだけど、今は流し読みしただけ。
 時間が欲しい。繰り返し練習したら追記しよう。

 Rails、Ruby、テスト、git、haml、html、css、JavaScript等々を同時に覚えていくのは相当無理があると思い始めた今日この頃。
 でも、やりたい事を無理無く実現するためには筋の通った方法を一つだけでも持っていないと…。

2014年6月22日日曜日

コンソールをサンドボックスモードで起動する

$ rails console --sandbox
Loading development environment in sandbox
Any modifications you make will be rolled back on exit
>>
コンソール上でいろいろいじっても、これで退出時に全てロールバックされて変更は無かった事になるそう。テストのときに使えそうですね。
 でも、そもそもサンドボックスってなんだよ、と。

マイグレーション

rails generate model User name:string email:string
上のようにrails generate modelやrails generate scaffoldでモデルを作成すると、データベースを作成するためのスクリプト(マイグレーションファイル)を/db/migrateに自動で生成してくれる。それを適用・展開することをマイグレーションと言うらしい。
 コマンド一つでマイグレーションできます。
$ bundle exec rake db:migrate
SQLとか全然知識無いのに自動でやってくれるんですって。嬉しい。昔PHPmyAdminとか使っても、???って感じになって自分の頭の悪さに感心した思い出があります。

 マイグレーションって聞くと、個人的にはRAID レベルの移行とかが頭に思い浮かんでしまいますね。
 ブログに記していると、Railsチュートリアルが進まなくて本末転倒になります。本末転倒虫。

 マイグレーションは以下で取り消しができる。
$ bundle exec rake db:rollback

2014年6月20日金曜日

rails generate controller AdminUsers action --no-test-framework

 コントローラを作成するときのコマンド。
 4番目がコントローラ名。単語の頭文字を大文字、スペース入れずに表現することをキャメルケース(ex. AdminUsers)と言うらしいけど、このルールに沿って決める。基本的に複数形。コントローラの意味合いからこの辺は決める。
 実際に配置されるファイルは、単語間がアンダースコアで区切られたスネークケース(ex. admin_users)で準備される。

 必要なアクションはこの時点でオプションに入れて作れる。
 アクションを作らない場合は、コントローラにアクションの定義とアクションのhtmlを作成する。

 --no-test-frameworkは、RSpec利用時にテストページが勝手に作られないようにするオプション。

 参考にしたサイトではRailsチュートリアルが3日間で終わったと書かれていた。私なんてググりググり進めて4章終わるのに10日以上かかったかもしれない。死んだ方がいいのかもしれない。うーーー、よん!ふぉー。

参考:

Gitの初期設定と基本操作

 GitはGUIになれているダメな人間からすると、いったい今どんな状況なのかわかりにくくて不安になるバージョン管理システムです。が、大変有用らしい。

 インストール後、端末ごとに一回だけ行うイニシャライズ。
$ git config --global user.name "あなたの名前"
$ git config --global user.email your.email@example.com
  Railsチュートリアルでは、長い予約コマンドのエイリアスを作っておくと便利だと書かれています。下記はcheckoutをcoとする例。
$ git config --global alias.co checkout
下記でgitコマンドの結果をカラー表示できる。
$ git config --global color.ui true
git configの設定値を確認するには-lオプション。
$ git config -l 

参考:
git config 備忘録

 コアエディタも設定しています。例ではSublime Textに設定しています。commit時にエディタが起動してコメントを記入できたりもします。保存して閉じるとターミナルに戻される。
$ git config --global core.editor "subl -w"
アプリケーションのルートディレクトリでリポジトリの初期化。
$ git init
Initialized empty Git repository in /Users/mhartl/rails_projects/first_app/.git/
 ルートにある.gitignoreファイルで、Gitの管理対象から除外するファイル・ディレクトリを指定します。以下はRailsチュートリアルで推奨していたもの。
# Ignore bundler config.
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
bundler_stubs/ #RVM使用時
ファイルをGitに追加する。再起的に処理されるので、'.'であればルートディレクトリとそのサブディレクトリを含めて全てが対象となる。
 追加後、且つコミット前のこの状況(抽象的ですが待機場所)はステージングエリアと呼ばれる。
$ git add .
コミット前のファイルを確認するには、下記のgit statusコマンドを使う。
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   README.rdoc
#       new file:   Rakefile
 変更を保存(コミット)するには、git commitを使う。-mオプションで、続く文字列がこのバージョンのコメントとして入る。
 -mオプションをつけない場合、コマンド実行後にコメントを聞かれる。
$ git commit -m "Initialize repository"
$ git commit
 コミットの履歴はgit logで確認できる。logの閲覧モードからは'q'キーで抜けられる。
$ git log
commit df0a62f3f091e53ffa799309b3e32c27b0b38eb4
Author: Michael Hartl <michael@michaelhartl.com>
Date:   Thu Oct 15 11:36:21 2009 -0700
  Initialize repository
その他にもこんな表示方法がある。
$ git log --oneline   # 1行ずつの簡易ログ表示
$ git log -p             # 過去commitの詳細表示
$ git log -stat         # 最新commitの統計的な変更状況表示
$ git diff                 # 最新commitと現在との内容比較
$ git diff --cached  # ステージング後のファイルは--cachedオプションをつける
 あまり複雑なことをしようとしたら、素人的にはcuiよりもSourceTreeとか使った方が絶対いいけど。間違いもないし。

 gitで管理していてもあたしなんて乱暴にエクスプローラからファイルを追加したり削除したりしちゃってるけど、本来はgit管理上での操作を明示的にするためにターミナル上で下記のように削除や移動、リネームをすべきらしい。
$ git rm index.html
$ git mv index.html index.html.erd

ルーティング

 routes.rbでの表現について。

 Railsチュートリアルを始めたときには、以下の表現を習いました。
 'static_pages/about'にGETの要求があったら応答してね、という単純なもの。
get 'static_pages/about'
 でもRails的には下記の表記の方が一般的だと。ややこしや。
 /aboutへのGET要求に対しては、static_pagesのaboutアクションへルーティングされる、と。あ、でも上よりは設定が柔軟にできそうですね。
match '/about', to: 'static_pages#about',  via: 'get'
ルート'/'へのルーティングも上と同様の表記はできるけど、一般的には下記の表現をする。
root  'static_pages#home'
これだけでいいみたい。

 あ、あと、routes.rbの変更を適用するには、サーバーを再起動する必要があるみたい。
 もう一つ。routes.rbで設定しても、静的ファイルがpublicに存在するとそちらへのルーティングが優先されるみたい。public/index.html等はリネームするなり削除するなりしておく必要があるっぽい。

参考:
ルート(/)へのルーティング設定

Asset Pipeline

 まずアセットってなんだよ、と。ここではWEBサイト構築する上での資源とか要素とか、そういう意味でいいのかな。
app/assets: 現在のアプリケーション固有のアセット
lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
vendor/assets: サードパーティのアセット
このディレクトリが静的ファイル(CSS、JavaScript、画像等)の標準的な配置場所になり、どのディレクトリを使うかがマニフェストファイルで設定されているようですが、デフォルトで適切に設定されているらしい。

 例えばapplication.cssでは下記の記述があり、これは自分自身とカレントフォルダを自動的にインクルードする設定なんだそうです。
*= require_tree .
 *= require_self
 必要なアセットを画面表示できるようにするため、マニフェストファイルに沿って結合した後、プリプロセッサエンジンにより最終的に使える形式(html/css/javascript)に変換されます。
 例えば、foobar.js.erb.coffeeであれば、後ろの拡張子から順にCoffeeScript、Rubyと解釈され、最終的にJavaScriptが生成される、と。

 あれ、メモというよりはチュートリアルを書き写しているだけになっている。
 Railsって、自動で行われることが多くて、親切だけど知らないと修正するにもどこをいじればいいのやらさっぱりわかりません。

application.cssとそのディレクトリ

 application.cssのある下記ディレクトリのcssファイルは、Asset Pipeline(よくわからない)によりapplication.cssの一部として自動的にインクルードされるそうな。
app/assets/stylesheets

htmlレイアウトの基本

<!DOCTYPE html> #HTML5の宣言
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag "application", media: "all",
                                           "data-turbolinks-track" => true %> #CSSのインクルード
    <%= javascript_include_tag "application", "data-turbolinks-track" => true %> #JavaScriptのインクルード
    <%= csrf_meta_tags %> #CSRF攻撃対策を有効化。
    <!--[if lt IE 9]> #IE9よりも古いIEの場合はHTML5 shimというスクリプトをインクルードしてHTML5に対応できるようにしている。
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
  </head>
  <body>
    <header class="navbar navbar-fixed-top navbar-inverse">
      <div class="navbar-inner">
        <div class="container">
          <%= link_to "sample app", '#', id: "logo" %>
          <nav>
            <ul class="nav pull-right">
              <li><%= link_to "Home",    '#' %></li>
              <li><%= link_to "Help",    '#' %></li>
              <li><%= link_to "Sign in", '#' %></li>
            </ul>
          </nav>
        </div>
      </div>
    </header>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>
  '#'はスタブURLというらしい。なんじゃらほい。ダミーってことかい?
 ググると、まぁそんな感じらしい。関数の場合には定数を返すだけ、とか。
 仕組みは後回しにして見かけだけ作ったものがモックアップで、そこに設置された動かないモジュールをスタブというのね。カタカナ好きねぇ。

 header、nav、sectionなんてhtml5のタグは覚えておく必要があるみたい。BootstrapというTwitterで利用されているデザインフォームを利用する場合には重要になるらしい。


stylesheet_link_tag

 CSSをhtmlに組み込むときに使う。
 CSSもhtmlもふんわりとしかわからないから、Railsチュートリアルを読む準備ができていないという噂もありますが、頑張ります。

 基本としてhtmlにCSSを組み込む際には下記のようなリンクをhtmlのheader内に記述する。
<link href="default.css" rel="Stylesheet" type="text/css" />
Railsだと、下記で良いそうな。拡張子もパスもいらない。(app/assets/stylesheetsまでは補完されるみたい。)
<%= stylesheet_link_tag "default" %>
でも、Railsチュートリアルでは下記の表現がされていて、なんですか?って話です。
<%= stylesheet_link_tag "application", media: "all",
                                       "data-turbolinks-track" => true %>
始めのapplicationがcssのファイル名(パス)。次がcssで指定できるmedia属性。(特別な場合を除いてallでよさそう。)
 turbolinksについてはよくわかりませんが、”ページ遷移をAjaxに置き換え、JavaScriptやCSSのパースを省略することで高速化するgemで、Rails 4からはデフォルトで使用され”ているそうです。パースってなんすか。ググったら構文解析とか。そういう処理を飛ばすってことかな。いいや、今は。そんなことがあるらしいと思っておこう。

参考:
media属性を使った媒体別のスタイルシート
Rails 4のturbolinksについて最低でも知っておきたい事

4.6 演習 4. (hashをmergeする)

 二つのハッシュをmergeメソッドで一つにまとめることができる。
rb(main):103:0> h  = {:a=>"a", :b=>{ :aa=>"aa" }, :c=>"c" }
=> {:a=>"a", :b=>{:aa=>"aa"}, :c=>"c"}
irb(main):104:0> h2 = {:x=>"x", :b=>{ :bb=>"bb" }, :c=>"c" }
=> {:x=>"x", :b=>{:bb=>"bb"}, :c=>"c"}
irb(main):105:0> p h.merge( h2 )
{:a=>"a", :b=>{:bb=>"bb"}, :c=>"c", :x=>"x"}
=> {:a=>"a", :b=>{:bb=>"bb"}, :c=>"c", :x=>"x"}
競合しているキーは、引数側で上書きされるそうな。

 それにしても、hashをmergeするとかって嫌な表現だ。日本語しゃべりたいよ。仕方ないけど。

参考:
[Ruby] 便利な組み込みクラスのメソッド達(Hash編)

4.6 演習 3. (ネストされたハッシュ)

 ハッシュをネストする、なんて言い回しされるとわけわかりません。
 要するに入れ子構造になっているということ?私の感覚としては、入れ子というよりはツリー構造の方がイメージに合うんですが間違っているのかな。長い枝があったり短いのがあったり、必ずしも格子状にデータがびっしり埋まっている訳ではないと思うのでなんとなく。
irb(main):087:0> z1 = { x: "1", y: "10" }
=> {:x=>"1", :y=>"10"}
irb(main):088:0> z2 = { x: "2", y: "20" }
=> {:x=>"2", :y=>"20"}
irb(main):089:0> z3 = { x: "3", y: "30" }
=> {:x=>"3", :y=>"30"}
irb(main):099:0> ps = { a: z1, b: z2, c: z3 }
=> {:a=>{:x=>"1", :y=>"10"}, :b=>{:x=>"2", :y=>"20"}, :c=>{:x=>"3", :y=>"30"}}
irb(main):100:0> ps[:a]
=> {:x=>"1", :y=>"10"}
irb(main):101:0> ps[:a][:x]
=> "1"
irb(main):102:0> ps[:c][:y]
=> "30"
結果としてうまくいっているように見えるけど、もっとうまいやり方がありそう。今はいいや。概念はなんとなくわかったと思う。

2014年6月19日木曜日

BABYMETAL その3

 あ、ちょうどBABYMETALの紅月(あかつき)がかかった。

 SU-METALは歌っているときの美しさが尋常じゃない。好きすぎる。困った。
 人も声もまっすぐで、儚さが半端じゃない。切ねぇ。俺節だったら、せづねぇよオギナワァァ、うたってけろじゃぁぁ!とか、そんな感じだと思う。(突然思い出したから、雰囲気だけです。俺節。)

 今から、すぐに解散してしまうだろうかと心配してみたり、でももし声が出なくなったらいさぎよく解散して新たな活動をしてほしいとも思うし、YUIMOAも含めてBABYMETALはこの瞬間に危うく成り立っていることがよくわかるので、期待はあるけど惜しまれて解散するまでをプロデュースしてあげてほしいと願うばかり。

 あぁ、なんなんだ。

 BABYMETALの解散は、幸せの死であってほしいよ。

 10代で解散ならまだ3人ともなにをやるにも困らないだろうけど、自分の娘のことのように心配なんだよ!

 個人的には解散する前に3人のボーカルを最大限に生かした本格メタルアルバムを作ってほしい。せっかく狐様だから、ながれで日本の神話をモチーフにしたコンセプトアルバムとかね。

 はーあ。なに書いてんだか。おしまい。

4.6 演習 1.&2. (関数とクラス)

 Railsチュートリアルのこの簡単な演習でなんかちょっとだけクラスがわかったような気がする。

 やっていることは同じだけど、上は関数として定義している。
 BABYMETALが分解、シャッフルの後、再構成されます。
irb(main):002:0> def string_shuffle(s)
irb(main):003:1>   s.split('').shuffle.join
irb(main):004:1> end
=> nil
irb(main):006:0> string_shuffle("BABYMETAL")
=> "YLEMBBATA"
 下はクラスStringにshuffleメソッドを追加し、同じことを実現している。
irb(main):030:0> class String
irb(main):031:1>   def shuffle
irb(main):032:2>     self.split('').shuffle.join
irb(main):033:2>   end
irb(main):034:1> end
=> nil
irb(main):035:0> "BABYMETAL".shuffle
=> "BTBALAMYE"
でもあれですよ。こう思考して記述することにどのようなメリットがあるのかがまだわからない。センスなさすぎる。
 半年くらい学校に通いたいよな。教えてくれる人も欲しいけど、一緒に苦しんでくれる人が欲しい。
 近所にいる中学生の姪とかが一緒に始めてくれないかな。後々、え!?この子がWEBエンジニアなの?みたいになって話題につきないというか、私が置いてけぼりにされそうだけど。

部分テンプレート

<%=render :partial =>'shared/link' %>
<%=render partial: 'shared/link' %>
 部分的に使い回せるhtmlは、上記のように呼び出して再利用できるそうです。
 テンプレートファイルのファイル名は頭に"_"(アンダースコア)をつけることがルールとのこと。
 場所は該当するコントローラ内や、コントローラをまたいでいろいろ使えるものであれば下記のsharedフォルダが一般的だそう。
app/views/shared/_link.html.erb
出来上がったサイトのソースを見ても、まだまださっぱりわかりませんね…。

 あと、Railsチュートリアルだとpartial:が抜けている。省略できるのかな…。

ローカルをリモートブランチで強制的に置き換えたい

git fetch origin
git reset --hard origin/master
参考:
gitでリモートのブランチにローカルを強制一致させたい時

 master以外でのpullでは下記のようなコマンドも。どっちがいいのかはよくわからない。
git branch new-branch origin/new-branch
参考:
git pullの詳細な挙動を追ってみる

git commitの上書きと取り消し

 ど素人なもので、commitしたのにあれ?まだやることあった、なんてことは日常茶飯事です。
 以下は覚えておかないといけません。

 まずamend。コミット後にファイル操作を追加した場合、前回のコミットを再適用(上書き)してくれます。でもこれはlogに残るので私のやりたいことではないみたい。
 amend(ment)にはあまりいい思い出がありません。英語なんて読めないのに仕事で英文の契約書agreementを読む必要があって、なんとか読み終わったら今度は長い追加・補足契約書amendmentが出てきたことを思い出します。
$ git commit --amend
コミットそのものを取り消してしまいたいときには以下を。これこれ。これがやりたいこと。HEADを一つ前のコミット時に移動させる意味?
$ git reset --soft HEAD^
下記でコミットと合わせてファイルの修正点も以前の状態に戻るようです。
 git reset --soft と git checkout -f、両方の性質を持っているということかな。まぁ、無闇に使うものではないのかも。
$ git reset --hard
間違ってresetしちゃった!ってときはORIG_HEADでreset前に戻れる。
$ git reset ORIG_HEAD 
下記の記事はHEADの意味も含めてわかりやすかった。

参考:
git reset についてもまとめてみる
【git】SourceTreeで解説!間違えたときのgitコマンドとやり方
GitのHEAD/ORIG_HEAD/FETCH_HEADについてのメモ

ユーザークラスとインスタンス変数

 @から始まるインスタンス変数はビュー内で自由に使えるようになる。以下はその例。

 アプリケーションのルートディレクトリに下記ファイルを配置。
example_user.rb
class User
  attr_accessor :name, :email #アトリビュートアクセサを作成するとゲッターとセッターも作成され、これによりどのビューでも利用可能となる。
  def initialize(attributes = {}) #User.newで自動で呼び出されるメソッド。
    @name  = attributes[:name]
    @email = attributes[:email]
  end
  def formatted_email
    "#{@name} <#{@email}>"
  end
end
Railsコンソールで以下を実行した。
irb(main):001:0> require './example_user'
=> true
irb(main):002:0> example = User.new
=> #<User:0x007fbc4ca30600 @name=nil, @email=nil>
irb(main):003:0> example.name
=> nil
irb(main):005:0> example.name = "Example User"
=> "Example User"
irb(main):006:0> example.email = "user@example.com"
=> "user@example.com"
irb(main):007:0> example.formatted_email
=> "Example User <user@example.com>"
雰囲気はわかるけど、ちょっと頭に入ってこない。 そうです。わかってません。

 ちなみにrequireはファイルの読み込みに使い、includeは「モジュールが持ってる性質を、クラスに組み込むメソッド」とのこと。モジュールの特徴をクラスに追加するイメージのようだけど、ファイル読み込むのとどう違うんだか。
 頭がついていかないので、そのうち体で覚えます。

参考:
requireとincludeとextendとmodule_function(1)

コントローラクラス

 継承については漠然と理解しているけど、意味合いとかがよくわかっていない。
irb(main):028:0> controller = PagesController.new
=> #<PagesController:0x007fdf3da68cf8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>
irb(main):029:0> controller.class
=> PagesController
irb(main):030:0> controller.class.superclass
=> ApplicationController
irb(main):031:0> controller.class.superclass.superclass
=> ActionController::Base
irb(main):032:0> controller.class.superclass.superclass.superclass
=> ActionController::Metal
irb(main):033:0> controller.class.superclass.superclass.superclass.superclass
=> AbstractController::Base
irb(main):034:0> controller.class.superclass.superclass.superclass.superclass.superclass
=> Object
irb(main):035:0> controller.class.superclass.superclass.superclass.superclass.superclass.superclass
=> BasicObject

クラスとは

Rubyは、多くのオブジェクト指向言語と同様、メソッドをまとめるのにクラスを使用しています。これらのクラスからインスタンスが生成されることでオブジェクトが作成されます。オブジェクト指向プログラミングの経験がない方にとっては何のことだかわからないと思いますので、いくつかの具体例を示すことにします。
確かにわかりません。
 しかもこの後の説明に更にコンストラクタという意味不明な単語…。

 とりあえず例を。
irb(main):059:0> class Word
irb(main):060:1>   def palindrome?(string)
irb(main):061:2>     string == string.reverse
irb(main):062:2>   end
irb(main):063:1> end
=> nil
irb(main):064:0> w = Word.new
=> #<Word:0x007fdf3de030e8>
irb(main):065:0> w.palindrome?("unko")
=> false
irb(main):066:0> w.palindrome?("panap")
=> true
でも、単語は文字列なので、わざわざクラスを作るのは不自然らしい。以下の通り、上位のStringクラスで 使用できるメソッドを継承させる方が自然。
irb(main):001:0> class Word < String
irb(main):002:1>   def palindrome?
irb(main):003:2>     self == self.reverse
irb(main):004:2>   end
irb(main):005:1> end
=> nil
irb(main):006:0> s = Word.new("panap")
=> "panap"
irb(main):007:0> s.palindrome?
=> true
irb(main):008:0> s.length
=> 5
irb(main):009:0> s.class
=> Word
irb(main):010:0> s.class.superclass
=> String
irb(main):011:0> s.class.superclass.superclass
=> Object
irb(main):012:0> s.class.superclass.superclass.superclass
=> BasicObject
selfはオブジェクト自分自身を表している。
 最後の方でクラスの継承について確認している。

 正直、まだクラスの立ち位置というか、どういうことなのかボンヤリしたところがあります。

 はっきり頭の中で整理がついたら追記したいと思います。

参考:
rubyのクラスやらモジュールがモヤっとしている人へ
クラス・モジュールの概念 Ruby

ブロック

 配列や範囲は、下記のようにブロックという表現とともに様々なメソッドに応答が可能なんだと。
 このシンプルな例だけでもわかる気がする。スプレッドシート上でやるような計算を式化したようなイメージと思えばいいのでしょうか。
 非常に奥が深いとチュートリアルにも書かれているので、ここでは適当にふんふん頷くだけにしておきます。
irb(main):045:0> (1..5).each { |i| puts i ** 2}
1
4
9
16
25
=> 1..5

irb(main):046:0> (1..5).each do |i|
irb(main):047:1*   puts i ** 2
irb(main):048:1> end
1
4
9
16
25
=> 1..5

配列について

 配列の特徴を適当に列挙しておく。

・配列のインデックス(番号)はゼロから始まる。ゼロオリジンと言うらしい。0 1 2 3…。

・インデックスにはマイナスにより最後の値から指定できる。最後の値のインデックスは-1。
irb(main):012:0> a = [3, 5, 7, 11]
=> [3, 5, 7, 11]
irb(main):013:0> a[0]
=> 3
irb(main):014:0> a[3]
=> 11
irb(main):015:0> a[-1]
=> 11
irb(main):016:0> a[-2]
=> 7
・その他のメソッドでの配列指定や論理式。
irb(main):017:0> a.first
=> 3
irb(main):018:0> a.second
=> 5
irb(main):019:0> a.last
=> 11
irb(main):020:0> a.last == a[-1]
=> true
・値の追加。異なる値の型も共存できる。push
irb(main):022:0> a.push(4)
=> [3, 5, 7, 11, 4]
irb(main):023:0> a << 6
=> [3, 5, 7, 11, 4, 6]
irb(main):024:0> a << "unko" << "anko"
=> [3, 5, 7, 11, 4, 6, "unko", "anko"]
・連結と分割。join split
irb(main):029:0> a.join
=> "3571146unkoanko"
irb(main):030:0> a.join(',')
=> "3,5,7,11,4,6,unko,anko"
irb(main):031:0> "unko anko punk".split
=> ["unko", "anko", "punk"]
irb(main):032:0> "unkoxankoxpunk".split('x')
=> ["unko", "anko", "punk"]
・範囲。
irb(main):037:0> a = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):041:0> a[0..a.length-2]
=> ["unko", "anko", "pink"]
irb(main):042:0> a[1..-1]
=> ["anko", "pink", "monk"]
irb(main):044:0> a = ('a'..'f').to_a
=> ["a", "b", "c", "d", "e", "f"]
・文字列に変換。
irb(main):039:0> a = %w[unko anko pink monk]
=> ["unko", "anko", "pink", "monk"]
irb(main):040:0> a[2..3]
=> ["pink", "monk"]

SPec等のテストは必要か

 テストを重ねつつ間違いの無いコードを書いていくのが定石らしいのですが、個人で開発する場合もみんなこれを方針として取り入れているのでしょうかね…。
 まだ面倒ばかりが目立って大きなメリットが感じられないのですが、この辺は追々なれていきたいと思います。

 失敗して初めて必要と感じるものかもしれないし。

module ApplicationHelper

 モジュール定義は、関連したメソッドをまとめる方法の一つで、Rubyのクラスにincludeを使うことでミックスインすることが可能。
 またこういう言い回し…。

 でも、このヘルパーモジュールは、Railsが自動的にインクルードしてくれるのでなにも設定しなくても全てのビューで利用可能になるそうな。
app/helpers/application_helper.rb

module ApplicationHelper
def unko(bitch)
~
end
def ~
~
end
end
このunkoメソッドはどこでも使える、と。

メソッドの定義

irb(main):041:0> def string_message(string)
irb(main):042:1>   if string.empty?
irb(main):043:2>     "It's an empty string!"
irb(main):044:2>   else
irb(main):045:2*     "The string is non-empty."
irb(main):046:2>   end
irb(main):047:1> end
=> nil
irb(main):048:0> puts string_message("")
It's an empty string!
=> nil
irb(main):049:0> puts string_message("unko")
The string is non-empty.
=> nil
こんな書き方でもいいみたい。
 returnによって返り値を明示的に決めることができる。
irb(main):056:0> def string_message(string)
irb(main):057:1>   return "It's an empty string" if string.empty?
irb(main):058:1>   return "The string is non-empty."
irb(main):059:1> end
=> nil
irb(main):060:0> puts string_message("")
It's an empty string
=> nil
irb(main):061:0> puts string_message("unko")
The string is non-empty.
=> nil
 3行目のreturnは無くても、直後にendで定義が終了するので問題ない。

オブジェクトとは

 オブジェクトとは、メッセージに応答する全て。というか、全て、だそうです。
 オブジェクト、オブジェクトって確かにピンとこない。端的に言って上の通りだと言われても、端的すぎてどうも…。

 この辺の説明なんてなんか笑ってしまうし。クラス、オブジェクト、インスタンスと。なんなんでしょうか。
 Railsチュートリアル内の言い回しからすると、メッセージ ⊃ メソッドというイメージらしい。


 こんな図はわかりやすい。(Googleのキャッシュにしか存在しないようなので拝借しました。)この理解で正しいのだろうか。

 下記のように、.〜(ドットなんとか)で指定されるメソッドの対象になる左側のものをオブジェクトと言うのかな。最小単位としては。複雑なオブジェクトはオブジェクトの集合体?
irb(main):021:0> 'unko'.length
=> 4
irb(main):022:0> ''.empty?
=> true
  empty?の?はemptyであるかどうかを理論値で返すRuby独特の言い回し、慣習だそうです。

puts と print と nil

 putsメソッドはprintと違って、最後に改行が出力されるそうな。もっち違いがあるのかもしれないけど、とりあえず今はこれだけ。
irb(main):014:0> print 'unko'
unko=> nil
irb(main):015:0> puts 'unko'
unko
=> nil
irb(main):016:0> print "unko\n"
unko
=> nil
irb(main):017:0>
どちらも、副作用的にリテラル(文字列)'nil' を返り値として返すそうです。
 'nil'はRubyで無を意味する値。

rails console

 Railsコンソールは、Railsアプリケーションを対話的に実行できるコマンドラインツール。素晴らしい学習ツールだとRailsチュートリアルは言っております。

 スタックから抜けるにはCtrl+C、コンソールを完全に終了させるにはCtrl+Dだそうです。
$ rails console
Loading development environment (Rails 4.1.0)
irb(main):001:0> first_word = "foo"
=> "foo"
irb(main):002:0> second_word = "bar"
=> "bar"
irb(main):003:0> "#{first_word} #{second_word}"
=> "foo bar"
irb(main):004:0> '#{first_word} #{second_word}'
=> "\#{first_word} \#{second_word}"
irb(main):005:0>
 とかね。

 どうでもいいけど、fooとかbarとか、よく出てくるけどなんだろうかと思ったら、日本で言うhogeとかpiyoと同じらしい。
 前の会社で詳しい人がこういうのよく使っていて、なんか内輪用語みたいで気持ち悪いな、と思っていたんですよね。素人相手にはオタクっぽいから使わない方がいいんじゃないかと。
 で、そういうのと同じなんですね。でもこれは郷に入れば郷に従えというやつでしょうかね。素直に受け入れましょう…。

メタ構文変数

ハッシュとは?シンボルとは?

 ハッシュって意味が分からない。
 配列の値を特定するためのキーは通常の配列では数値(インデックス)だけど、ハッシュ(連想配列)では文字列を使うみたい。
irb(main):049:0> user = {} #ハッシュを定義、初期化する
=> {}
irb(main):050:0> user["u"] = "unko"
=> "unko"
irb(main):051:0> user["a"] = "anko"
=> "anko"
irb(main):052:0> user["u"]
=> "unko"
irb(main):053:0> user #リテラルな表記で返される
=> {"u"=>"unko", "a"=>"anko"}
irb(main):054:0> user = { "p" => "pink", "t" => "tank" } #複数同時に代入できる
=> {"p"=>"pink", "t"=>"tank"}
irb(main):055:0> user
=> {"p"=>"pink", "t"=>"tank"}
ちょっとわかった気がする。
 でもシンボルはもっとわからない。Railsではハッシュではなくシンボルの方がよく使うそうです。
シンボルはハッシュのキーとして利用するのですが、"unko"のようなリテラルではなく :unko のように頭にコロンを置きます。しかもRuby1.9からは下記のような表記も許され、一般的になっているそうな。大混乱。
{ :name => "unko", :email => "unko@unko.com" }
{ name: "unko", email: "unko@unko.com" }
2番目の表記ではシンボルにハイフンが使えないんですって。更に大混乱。ルールが細かい。
 チュートリアルではシンボルについて明解な説明は無かった?読み飛ばしたのかな。結局、なぜRailsではシンボルを主に使用するのか、よくわからなかった。書式はなんとなくわかったけど。

参考:

2014年6月18日水曜日

ファイル名・テーブル定義等のルール(規約)

ファイル名の規約
ディレクトリ
ファイル
クラス名
親クラス

app/controllers/
xxxs_controller.rb
XxxController
ApplicationController

app/models/
xxx.rb
Xxx
ActiveRecord::Base

app/views/xxxs/
yyy.html.erb

app/views/layouts/
xxx.html.erb

app/helpers/
xxxs_helper.rb

db/migrate/
YYYYMMDDhhmmss_mmm_xxxs.rb
MmmXxxs
ActiveRecord::Migration

test/fixtures/
xxx.yml

テーブル名とクラス名
  • テーブル名は複数形
  • 単語の区切りはアンダーバー(_)
  • 対応するクラス名は単語の先頭を大文字にして _ を取り除いたもの

キーのカラム名
  • 主キーのカラム名は「id」
  • 外部キーのカラム名は「テーブル名の単数_id」

日付関連のカラム名
  • DATE型のカラムには名前を 「受動態_on」
  • TIMESTAMP型のカラムには名前を「受動態_at」
  • 更新日時、作成日時は「updated_at」、「created_at」

結合テーブル
  • 関連させたいテーブル名をくっつけた名前にする
  • カラム「id」を作らずに、関連させる2つのキーのセットを主キーにする

Railsプロジェクトのファイル構成

 とりあえず覚えられません。勉強しながら何度も見返します。

databaseを削除・再作成・再構成する

rake db:migrate:reset
データベースの扱いがよくわからなくて困るとたまに使います。

参考サイト

GEMをアップデートする

gem i rubygems-update
update_rubygems
gem -v
gem pristine --all

 gem updateは古いとかなんとか。よくわかりませんが、こちらを使うことにします。

BABYMETAL その2

 BABYMETALの1stアルバムから、好きな曲を順に並べてみたところ、SU-METALが大好きなことがわかりました。
 いや、最初から気づいていました。でもYUIMOAも好き。二人もガンガン歌ってほしい。
  1. メギツネ
  2. 紅月-アカツキ-
  3. 悪夢の輪舞曲
  4. ヘドバンギャー!!
  5. イジメ、ダメ、ゼッタイ
  6. ウ・キ・ウ・キ★ミッドナイト
  7. いいね!
  8. BABYMETAL DEATH
  9. Catch me if you can
  10. 4の歌
  11. ギミチョコ! !
  12. おねだり大作戦
  13. ド・キ・ド・キ☆モーニング
 基本的に純にメタルよりの曲が聴きやすいのですが、聴いているうちにウキウキミッドナイトと4の歌が微妙に良くなってきました。いいね!はメインの曲調とブレイクダウンのミスマッチ加減がハンパではなく。一緒にスローヘッドバンギングしたい。

 Youtubeの再生回数の多いギミチョコ!はちょっとやりすぎかなー。まぁ、あれで有名になったというのならそれは認めるけど、あんまり進んで聴いていない。
 とは言っても、イントロとかメタルが好きな人間としては響くところも結構ありますよね。

 あと、結果的に一番下になっちゃったド・キ・ド・キ☆モーニングも嫌いじゃない。要するに捨て曲無しの名盤なんだろうと思います。
 大好きな正統なメタルアルバムよりシリアスすぎず聴きやすくて中毒性は高いです。

 バンド付きの本気モードで紅白に出てほしいなー。

Gitでコミット前の編集を破棄する

% git checkout -f
タイトルとコマンド一行、なんてエントリーが増えるかもしれない。
 順序は行ったり来たりとカオスな状態でも、とにかくメモしておこう。

参考リンク

 追記。

 上だと変更は元に戻るけど追加されたファイルは削除されないので、下記でファイル確認と削除を行う。
 -dをつけるとディレクトリも対象にできるみたいだけど、試したらlog/とか怖いものを削除しようとしていたので、やらない方がいいかも。.gitignoreの対象が含まれちゃうのかな?
git clean --dry-run  #確認
git clean -f              #削除
参考:
Untracked Files を削除する

Ruby on Railsを独習します

 突然ですが、Ruby on Railsを覚えることになりました。小学生の頃に触ったBasic以来のプログラミングです。現時点でのバージョンはRails4です。
 途中で投げ出しそうなのでメモしながらジワジワ進めようと思います。(メモは自分の詰まったところが中心になると思います。)

 仕事で使えれば嬉しいのですが、素敵なサイトを作って広告収入で生きていければそれ以上に嬉しいです。仕事嫌いの人間として、一応大きな(?)野望を持ちつつ進めます。

 とりあえず教科書として、軸にしていくものは下記です。


 環境はしぶしぶMac。

 ロト6予想サイト、音楽等のキュレーションサイト等が個人的に作ってみたいものです。
 でも最初のゴールとしては、なんだろう。ごく単純なブログとかでしょうか。

 さて、頑張らない程度に頑張ってみましょう。