2014年7月29日火曜日

gem Pundit

 Punditはアクセス管理の認可(authorization)を実装するためのgemですが、これを使えと言われて使ったものの、下知識が足らず、Readme見ても簡単簡単と書かれている割にその通りにしてもうまくいかず、なんなんだよ、と。
 最終的に下記のページを参考にしました。この例を見る限りでは、簡単というほど簡単ではないように思うのですが…。
 ちなみにこのサイトの記事は実装までを完全に再現してくれてはいないため、リンク先のgithub上にある実際のコードが一番参考になりました。

参考:

 つれーなー。Rails始めて2ヶ月くらい経つけど、拒絶反応が取れた程度の進捗。本当に自分がふがいない。
 1人で楽しく自由に進めた方がこれに関しては良い気がする。ドットインストールの興味のある講座とか見たいけど、余計なことに時間を使うなとえらい人がキレたりするからな。なんなんだろう。吸収できるものから吸収して、ちょっとは感覚を持つというかちょっとでも自信をつけさせて欲しいよ。

2014年7月24日木曜日

アスペクト比を変えずに画像を縦横長の決まった範囲に収める

 例えば200*200というマスの中に画像を縮小して、且つアスペクト比を変えずに表示させたい。
 需要ありそうだけど、ググってもなかなか見つからない。

 縦か横のどちらかにだけ合わせるのであれば、cssにwidth: autoやらheight: autoやら書けば対応できるみたいだけど、これを縦横から挟むようなcss書いてもうまくいかない。

 とりあえず裏技っぽいのはあったので参考にリンクを張っておこう。

参考:
【図解】CSSだけで画像の縦横比を維持したサムネイルを表示する

 こんなの簡単そうなのにね。いや、きっとすげー簡単なんだよ。職人はきっと当たり前のように使っているんだ。うーむ。
 いろいろなページのソースを見てみよう。

 gemとか使って事前に切り出しとけよ、とかそういう話なんだろうか。
 切り出してRailsで使う方法はこの辺が参考になりそう。必要になったら読もう。

参考:
#374 Image Manipulation

 自分がRailsを質問すべき人が、キレてて質問しづらい。なんだよ。ちくしょー。優しく教えてくれよ。未経験だって言ったじゃないか。

数値を区切りや通貨単位を入れて表示する

 例えば変数priceに10000000.0と入っていたとして、それを10,000,000円と表示させたい場合、下記で対応可能なんですって。
number_to_currency(price, precision: 0, unit: "", format: "%n%u")
その他、整形に使えるヘルパーはたくさんあるようです。以下、参考まで。

参考:
[Ruby on Rails] 数字を整形する便利なViewヘルパー


新しいブランチとしてpushする

 gitはとても便利らしいけど、複数人で使っていると怖い。よくわかっていない。

 とりあえずローカルで新しく作ったブランチをリモートの新しいブランチとしてpushすることがよくあるので、メモ。
git push -u origin [new branch]
 -uすると、push先が同じであればその後ブランチ名が省略できる。

 こういう一面的な覚え方はいけないんでしょうけど、今は悠長に勉強している暇がない。

[未解決] Windows8.1マシンが自動スリープしない

 Windows8.1にしてから、というわけではないのだけれど、(ログを見ると)2か月前くらいから電源オプションで設定した時間が経過してもスリープにならなくなってしまった。

どんな操作やソフトウェアのインストールしたのかは記憶にないのだけれど、現状を書いておいておきます。

  • Windows8.1 Pro 64bit
  • ホームグループには不参加(パブリックネットワーク)
  • 思いつく全てのデバイスのスリープ復帰機能を停止
  • OS起動直後は問題なく動作する
  • 同じシステムで、XPの頃には問題なかった

 で、動画を再生した後に発生するような気がする!と思い始めたのが最近で、その辺のキーワードで検索したら下のサイトにたどり着いた。内容的に関係ありそうな感じもするので、試してみよう。

参考:
Windows8.1にアップデートしたら自動でスリープに移行しなくなった

イベントビューアーによるとたまにUSBルートハブが原因でスリープから復帰していたので、この線で相当デバイスをとったりつけたりon/offしたり調査していたのですが、こっちは関係ないのかな…。再現頻度も低いし、上の問題と連動している感じはしない。

 うーむ。

 また夜にでもイベントビューアーやらなんやらを確認してみよう。直っていたら嬉しいなー。

---

 で、その後、ネットワーク上の動画を再生して放置を繰り返してもちゃんとスリープに入れるようになりました。サンキュー、ブログの人!

---

 更にその後、頻度は少なくなったけどやはりたまにスリープに入らない。
 今はOneDriveとかOneNoteとかちょっとでもあやしいアプリケーションを削除したり停止したりしている。CCCもWindows8.1上でかなり変な動きしているんだよな…。
 あー、ここで改めてUSBルートハブか。またいろいろ確認してみよう。

---

 さて、スリープに入れない件を放置していましたが、今日イベントビューアーのApplicationを見てみると下記の情報がたくさんあったのでググってみた。
- System
  - Provider
   [ Name]  ESENT

  - EventID 103
   [ Qualifiers]  0

   Level 4

   Task 1

   Keywords 0x80000000000000

  - TimeCreated
   [ SystemTime]  2014-08-17T21:13:16.000000000Z

   EventRecordID 10418

   Channel Application

   Computer 1F-TV

   Security

- EventData
   svchost
   2876
   Instance:
   0
   [1] 0.000, [2] 0.000, [3] 0.000, [4] 0.000, [5] 0.016, [6] 0.000, [7] 0.000, [8] 0.000, [9] 0.000, [10] 0.000, [11] 0.000, [12] 0.000, [13] 0.000, [14] 0.000, [15] 0.000.
   0 

すると、スリープに関する記事がいくつか出てきて、いきなり核心に迫る感じ。
 参考にしたサイトのマネをして管理者権限のDOS上でpowercfg /requests。理由はわからないけど、Realtekオーディオをシステムがつかんだまま(逆?)のようです。
C:\WINDOWS\system32>powercfg /requests
DISPLAY:
なし。
SYSTEM:
[DRIVER] Realtek High Definition Audio (HDAUDIO\FUNC_01&VEN_10EC&DEV_0892&SUBSYS
_1043841B&REV_1003\4&1d1d2e48&0&0001)
現在 1 つのオーディオ ストリームが使用中です。
AWAYMODE:
なし。
実行:
なし。
PERFBOOST:
なし。

 対処法がよくわからなかったのでとりあえずデバイスマネージャーでドライバーの再更新(これまでと同じバージョンを再適用しただけ)をしたところ、この使用中ステータスは解消されました。

 さて、これで直るの?使用中になってしまう、という問題かもしれないな。ちょっと様子見。

参考:
Windows 8で自動スリープしなくなった時の対処
Windows: Windows7で自動スリープにならない場合の対処

---

 直らなかった。DOS上のステータスが変わっただけで今回の問題とは関係ないのかも。
 ストレージ関係の情報の中にヒントがありそうな気がするので、次はこの線を洗う予定。

---

 またしばらくして電源オプションを見ると、電源プランがSamsung High Performanceになっていた。SSDのアプリがなにかのタイミングでこの設定を変えるみたいだけど、こちらでも最初に書いたマルチメディアの設定を行ったら調子いいみたい。さて今度はどうなるかな。

---

 その後も相変わらず直らず、可能性として優先順を低く見積もっていたBIOS更新をやってみたら、なんかすごく調子いい…。まじかよ。
 Windows8のS3以上となんか衝突していたんだろうか。

 クローズできそうな気配。今週一杯問題が発生しなかったら終了にしよう。

---

 ダメでした。動画見たりいろいろ操作するとやはりスリープに入らなくなる。再起動すると戻る。なんだろか。うーん。
 もう一回イベントビューアで、Windows8をクリーンインストールした直後からか、8.1に更新してからか、どんな変更の後に問題が出るようになったか再確認してみよう。ちょっと記憶があやふや。

---

 その後もイベントビューアを追うのが面倒で、まずはドライバ更新と今一番怪しいと感じているCCCを一時的にスタートアップから外している。ドライバーが動いていれば十分なので。


2014年7月23日水曜日

条件式の左辺と右辺

 評価されるものを左辺に書こうと言われた。ふーん。あまり深く考えていなかった。

 例えば、片方が数値や文字列であれば自然と a == 5 と書けるけど、aとbのように変数同士だとどっちでもいいじゃんという気がする。
 でもaが自分の年齢で、bが評価される年齢だとすると、自分の年は定数的だから b == a と書く。

 こう考えるのがいいのかな。どちらが定数的か。それを右辺にする、と。

if not と unless

 if not(if !条件式)という書き方をしていたら、unlessの方が見やすい場合があると言われた。
 へー、そもそもそんな条件分岐の命令があることを知らなんだ。なんだしら。

 三項演算子とか、いろいろあるのね。
 ひとつの方法を応用するよりは、ちゃんと使い分けた方がすっきりするのかな??

参考:
条件分岐

Untrackedファイル

 Untrackedファイルってのはgitで追跡されていないので、addしないといけないものと勝手に思い込んでいた。
 テスト的に作ったファイル(アップロードした画像とか)も含めてしまっていたので、今後は注意せねば。

 git statusすると赤文字で表示されるから、commitできない困ったファイルという印象があった。単にいるかいらないかわからないよ、と言ってきているだけか。いらなきゃ放置か削除すればいい、と。あるいは.gitignoreに書くとか、かな。

参考:
2.3.4. 追跡されていない (Untracked) ファイル

Untrackedファイルを一括削除したい場合は下記の手順で確認しながら実行する。--dry-runの後に--interactiveするのがリスクが少なそう。手作業で削除するより早いし。--forceは無闇に使わない方が良さそうすね。
git clean --dry-run          # -nでもOK。Untrackedファイルの確認。
git clean --force             # -fでもOK。強制一括削除。
git clean --interactive     # -iでもOK。対話的に個別削除。

 ディレクトリも削除する場合は、-dらしい。

参考:
Untracked Files を削除する

例外処理

 まだ使ったこと無いけど、例外処理ってのを見かけたのでメモ。

 begin ~ rescue ~ else ~ ensure ~ endなんての使って、コードの処理がうまくできないときにエラーを吐かせるとか別の処理を行わせることができるって。便利そう。

参考:
Ruby on Rails 例外処理 begin

 あのえらい人の冷たい態度に毎日接しているとなかなかの殺意。一ヶ月前は面白そうなこと投げてくれて感謝していたのにね。
 全くの初心者だと言っていたのに、始めから何でも知っているかのように話してくるのやめてほしい。
 プロジェクトに必要な知識を独学で得ることと、プロジェクトの納期を合わせるなんて、普通初心者にできんの?

 まぁ、頑張ろう。頑張らないと逆に鬱憤がたまって殺しかねない!

データをcsvからインポートする

 例えばmodel/item.rbにデータを取り込むスクリプトimportを書いておいて、下記をターミナルで実行すればいいみたい。
rails runner Item.import

 スクリプトは、例えばこんな感じ。指定したcsvファイルからデータを吸い上げています。
require 'csv'
class Item < ActiveRecord::Base
def import
csv = CSV.read("#{Rails.root}/tmp/links.csv", encoding: "cp932")
csv.each do |link|
item = Item.new
item.title = link[1]
item.price = Float(link[2])
item.save
end
end

参考:

 なんだか怒りでわなわなする毎日。あのエライ人とこの先やっていけるんだろうか。8年前に初めて会った時に覚えた感情を思い出してきた。あのときもこんな感じの人だったような気がする。

2014年7月22日火曜日

認証と認可

 WEBサービスではアクセス制御の定石として、認証と認可があるんですって。保育園の話にしか聞こえない。
 これからdeviseとpunditというgemを使ってログイン管理をしようと思っているのですが、その準備段階の知識がそもそもなくて我ながら大丈夫かよ、と。

 ログインできるユーザーかどうか、というだけでなく、ユーザーの中でも権限ランクの違いがあるってあたりですかね。重要なのは。
 難しい言葉を使ってさも説明したかのような雰囲気出すの嫌いです。

 とりあえずこの辺を読んでわかったふりをしておこう。

参考:
第2章 アクセス制御 アクセス認可

数値と文字列の配列の論理演算がしたい

 例えば・・・
[15] pry(main)> a=[1,2,3]
=> [1, 2, 3]
[16] pry(main)> b=['3','4','5']
=> ["3", "4", "5"]

 こんな感じで二つの配列があってaにだけ存在する要素を抜き出したい場合、a-bをすればいいらしいですが、上の場合は数値の3と文字列の3が区別されてしまい、下記の通り期待とは違う結果が帰ります。エラーも無し。
[17] pry(main)> a-b
=> [1, 2, 3]
でも下記のようにするとbが数値の配列と見なされて期待する解が得られる。
[18] pry(main)> a-b.map(&:to_i)
=> [1, 2]

 多分、こういう事態になる前に対処すべきだと思うんだけどどうすべきかわからずとりあえず回避法が必要になりました。

参考:
ruby 配列の中の文字列を全部数値にしたい
Rubyでメタプログラミング ~暗黙的に呼ばれるto_procメソッド (.map(&:to_i)について)

要素の有無をチェックする

 ある変数があるかどうかを確認する場合、変数(配列)の場合は.present?、テーブル内に条件に見合う値があるか確認する場合は.exists?が使える。

.present?
[1] pry(main)> a=[1,2,3]
=> [1, 2, 3]
[3] pry(main)> a.present?
=> true

.exists?
[
5] pry(main)> Curation.pluck(:title)
(0.4ms) SELECT "curations"."title" FROM "curations"
=> ["てすと1", "テスト2", "て", "bav", "あああ", "aaaa", "aaa", "sfd", "aaa", "aaaa"]
[6] pry(main)> Curation.pluck(:title).present?
(0.2ms) SELECT "curations"."title" FROM "curations"
=> true

参考:
データの存在を確認(exists?)
Railsでnil? blank? empty? present?を使いこなそう

2014年7月21日月曜日

モデルのテストデータが欲しい

 手で入れてもいいのですが、開発メンバーが同じテストデータで検証したいときとかは、db/seeds.rbにデータを生成するスクリプトを書いておくと良い。
rake db:seed
で、上記コマンドを実行すればデータは生成される。

参考:
rake db:seedを使った初期データの投入

2014年7月19日土曜日

ダブルコロン (::) ってなんなの…

 二重コロン、これがなんかどうもしっくりこない。クラスメソッド? 

 すげーいい加減だけど、最初の考え方としては、:: と . が同じとしておこう。記号の右側が定数の場合は :: しか使えないルールがある、と。

参考:
2日目:Rubyの不思議な記法たち。
定数
(漫画のキツネと学ぶ)短時間の(そして願わくは辛くない)Rubyコース

 今日あたりは、Rails的に私にとってえらい人に非常な怒りを覚えている。未経験者に独習を言い渡し、一ヶ月後の今、厳しく納期を迫ってきている。Railsのテキストの例は挙げてもらっただけど、それを読むための知識を習得する方法と時間については全く考慮されていない。
 複数の形式のデータソースをまとめて、複数モデルを利用してなんだかんだと仕組みを作るのは、ちょっとスキルが不足し過ぎじゃないだろうか。やってみてはいるけど。遅いと言われたってオレが金出して外注するのでは本末転倒だし、なんなんだろうか。奴は。

コントローラの命名規則

 Javascriptの練習をしようと、Railsでテスト用のアプリケーションを作って適当にControllerを作ったところ、このコントローラ上のアクションに正しくルーティング書いても通らない。
rails g controller javascript_0719
こんな風にコントローラを作ったのですが、多分この_7019部分がいけなかったんだろうな。アンダースコアの後の数字は認められないのかも。常識かもしれない。
 別の名前で同じようにコントローラ作ったら問題なくできた。javascriptの勉強をする前に30分くらいつぶしてしまった…。

 ど素人なんで、テストで作ったものに番号振ったり日付入れたりしたくなるじゃないすか!しないすか?するっすよね!

参考:
コントローラの作成と命名規則(命名規約)

 おらー、だめかもしんねぇ。わかりかけているような気はするんだけどなぁ。

2014年7月18日金曜日

マイグレーションを1からやり直す

 rake db:migrateだとtableがすでに存在しているとエラーが出る(コンソールで確認してもそんなテーブル無いんだけど…)のに、下記だと問題は起きなかった。

rake db:migrate:reset
とりあえず、メモ。また使いそうな気がする。

git mergeやらrebaseやら

 gitでブランチが枝分かれすると非常に不安になる。特にリモートの場合は。なんかポキッと折ってしまいそうで。

 gitの概念を知れば怖さも少なくなる、ということでmergeとrebaseを知る必要が出てきました。
 何はともあれ下記を読んだら図解がわかりやすく、gitでのブランチの動き方がよくわかってきました。このブログに説明を書く代わりにリンク張ります。
 こういうイメージででしか頭に入らないのってアホな証拠だな。以前の同僚に同じこと言っている人がいて、非常に親近感の湧いた記憶があります。
 こういう開発している人たちの頭の中ってどうなっているんだろうか。えらい人はプログラマーにもバカがたくさんいてさーと言うがそのうちオレもそういわれるんだろうと思うと泣けてくる。



参考:
チーム開発に必要なgit コマンドを神速で習得しよう!

アソシエーションで作ったインデックスに値が入らない

 バカみたいにずっと考えていました。
 例えば、AuthorとBookが1:nの関係であるとき、Book.newしてもauthor_idに値が入らず困っていました。どこかでアクティブなauthor.idを拾って手動で突っ込むものと思っていたのですが、書式が全然違っていた。

 authorが決まった状態であれば、以下で正しくauthor_idが自動的に代入される。
@author = Author.find(1)
@book = @author.books.new
=> #<Book id: nil, name: nil, Author_id: 1, created_at: nil, updated_at: nil>
それにしても、テキストでこんなことしてたっけな。読み直すか。
 newの前がどうして複数形なのかもよくわからん。

頭悪過ぎだ。テキストを読んで理解できないし、例えわかっても次使うまでに忘れてしまう。ブログに書き留めてもあまり効果がないな…。

参考:
ActiveRecord の new と build の違い
Railsでの似たような言葉での違いメモ

知らない用語・略語

 みんな大好きな用語や略語。全く興味ないけど知らないとどうにもならないので覚えないと。仕方ない。
 説明は一言にして、リンクだけ張っていこう。

(ウェブ)ビーコン HTMLを利用したメールやウェブページの閲覧者を識別する仕組み

2014年7月16日水曜日

rails console --sandbox

 コンソールでデータベースの内容を壊さずに試したい場合、--sandboxをつけて実行するとコンソール終了時に実行した内容が全部ロールバックされてデータが元に戻る。便利。
~/work/t0716_2$rails c --sandbox
Loading development environment in sandbox (Rails 4.1.1)
Any modifications you make will be rolled back on exit
Ctrl+Dで抜けると、rollbackしたメッセージが表示される。
irb(main):016:0> ^D
   (0.1ms)  rollback transaction 

リレーションとかhas_manyとか

 has_manyとかbelongs_toとか、テキストでは概念は自明のような書き方でくるから酷い。
 そこへいつもの命名規則とかがあって大混乱。

 以下の参考リンク、一つ目は具体例の説明が超優しい。
 二つ目は〜_idとか言うキーについての説明が詳しい。マイグレーションの具体例が素敵でした。

参考:
アソシエーション
Rails4 外部キーをテーブルに設定するための、3通りのマイグレーションの書き方。

 あと、どの本でもモデル双方から設定しないといけないかのように書いてあることが多いけど、参照する方向だけ設定すればいいみたい。

 プログラミングつーもんは、リファレンスマニュアルかソースコードが読めるようになるまではなにも信用できないんじゃないかって気がしてきた。
 始めは各項目について詳しく語っているサイトのリンクを収集できれば、入門者にとっては一番良さそうに思う。

2014年7月15日火曜日

階層的なリンクを作る

 まだ使わないけど、こんな感じの階層的なメニューリンクの作り方があったのでメモしておく。カテゴリーを絞り込むようなイメージのやつ。これから作るサイトで使うかもね。

参考:
現在のページと同じページの場合はリンクを貼らない(link_to_unless_currentメソッド)

BABYMETAL その5

 掲示板にSU-METALについてエピソードがたくさん書かれていた。Youtubeの動画とかでもこの一片は確認できるので、おそらく全部本当なんでしょう。自分のために一応メモしておく。
★SU-METAL(中元すず香)とは
・運動神経が酷いので自転車に乗れない
・縄跳びの二重跳びは1回がやっとである
・さくら学院のステージでは1人だけ必死で踊って1人だけ汗だくである
・靴ひもを自分で結べない上に左右逆に履き指摘されるまで普通に歩いている
・靴下も左右違う物を履いている事が多い
・ニット帽を被る時は前髪を全部中に入れて帽子を直立にするのがこだわりである
・会話中に「なんかー」を連発し話が長いが中身はない
・ホイッスルを上下逆に持って吹こうとする
・よく漢字を間違えるがさくら学院生徒の名前も書き間違える
・さくら学院生徒の全員の名前を書いたつもりが菊地最愛を忘れている
・他の生徒のお茶を間違って飲む
・「力うどん」とは長年の職人さんが力づくで練ったうどんの事である
・「CD」や「BD」の「D」の意味は「デロリアン」である
・Perfumeライブの座席番号が暗号に見えた
・幼少の頃より1円玉貯金が趣味で緑に変色した1円玉を見て「レアな1円玉見つけた」と喜ぶ
・幼少の頃より引越しの際に募金するまでに集めた1円玉は800枚にも及ぶが額面で言うとたかが800円である
・MVやドキュメントの撮影時いつも置いてきぼりにされ「待ってよ?」というがみんなに置いてきぼりである
・メールの返信はだいたい2日後である
・ゆいもあ2人が仲良くしているのが羨ましくて一緒にお風呂に入ったり寝たりする寂しがり屋さんである
・日記をつけているが不定期で書き殴りである
・自室でネギを栽培し姉に叱られる
・ネギ栽培をきっかけに料理にはまるが作った料理はゆで麺と粉末スープのうどんである
・冷蔵庫にある物をとりあえず炒める
・無性に牛乳を飲みたくなる日がありその日は1日2リットル以上飲み腹を壊す
・骨つき肉や骨付きの魚は動物を食べてる感じがして好きじゃない
・アルバムのジャケ写撮影で「お気に入りの私物を持って来て」と言われて、お好み焼きのヘラを2本持参し嬉しそうに撮影に挑む
・同郷の杉本愛莉鈴を変人呼ばわりするが本人のほうがよっぽど変人である
・普段はボケているがいざという時に別人に変身する 
 もう、なんか可愛すぎるな。

ネストされたルーティングとform_for

 サンプルコードにちょっと編集機能を付けてみようと思ったら大ハマり。
 ルーティングがこんなネストされた構成の場合に、projectモデルとtaskモデルに対するform_forは書式にだいぶ違いがあった。基本に違いは無いんでしょうけど、直感的でなくてわからなかった。
resources :projects do
  resources :tasks
end
 projectの方は、ごく入門書的なコードで動いた。
コントローラ
  def edit
  @project = Project.find(params[:id])
  end
ビュー
= form_for @project do |f|
 taskの方は、1時間くらいウトウトしながら考えてダメで、ググったらすぐ出てきた。すぐググれば良かった。ggrksとはよく言ったものです。
コントローラ
  def edit
    @project = Project.find(params[:id])
    @task = Task.find(params[:id])
  end
ビュー
= form_for [@project, @task] do |f|
 まだ全然カスの領域から踏み出せない。

参考:

ドットインストール Ruby on Rails 4入門 (全28回)

 作ってほしいものがあるからRailsを勉強して、と言われたので素直に始めたらRailsの前に勉強しないといけないことがたくさんあって、でも時間無いから概念だけかいつまんでRailsの勉強をしています。
 1ヶ月ほど独習して最近1週間は結構吸収するペースがあがってきたのですが、最初のうちは途方に暮れていました。見よう見まねでやっても概要がつかめていないから頭に入らない。

 RailsチュートリアルとかRails Girlsとか、買うように勧められたパーフェクトRuby on Railsという本が最初のテキストでしたが、途中で投げ出しました。今振り返ると本当にWEBデザインやプログラミング初心者に勧めるべきものではないですね。
 勉強の進捗で結構せっつかれたけど、あれはどうなんだろう。下地やセンスのある人じゃないと無理。逆に本当の素人にこれらを勧めたセンスを疑う。全く知識がないことは何度でも言ったはずなんだけどね。
 後から、結局回り道してhtmlとcssとrubyの触りだけでもと勉強する必要があったと伝えたら、そういうこともあるかもしれないね、だって。なんすかそれ。Railsが少しずつ理解できるにつれて、全部怒りに変わっていくな…。
 まぁ、これで数ヶ月後にでもそれらしいものが作れるようになれば感謝すべきなのかな。話を振ってくれたわけだし。

 上記では一回目の説明からかなりの情報を詰め込もうとしている。特にいけないのが、何が重要かをあまり説明していない。開発にあたって覚えるべきノウハウの優先度ってあると思うんですが、そういうものについて全く語られていない。
 例えば項目ごとに3段階くらいの優先度がつけられていて、何度も復習しながら優先度の低いものまでを習得していく、という本があればいいのにな。

 ところで、いろいろ困ってドットインストールというサイトの動画を見ると、内容としては薄いんでしょうけど、優先度の高いものしかやらないし、次に何をどのようになぜするのかというのを話しながら教えてくれるので考え方が見えてとても参考になった。
 リアルな授業と違って、疑問を持ったところを何度も聞き返すことができるのも嬉しい。


 htmlとcssもここで見ました。Rubyについては入門書を図書館で読んだけど、あとでここの動画を見ておこうと思います。
 Railsで最低限必要なJavascriptとデータベースに関してはまだ全く勉強していないので、これも動画を見ておこうかな。これ見てから本読むとだいぶ感触が違うと思う。

 hamlの講座も見ましたが、これはhtmlより入力文字数が相当減って助かってます。

 これで無料だなんて嬉しい限りです。

2014年7月14日月曜日

validationのエラー内容を表示する

%h1 Add New
= form_for @project do |f|
  %p
    = f.label :title
    %br
    = f.text_field :title
    - if @project.errors.any?
      = @project.errors.inspect
  %p
    = f.submit
 例えばこんな感じで、.errors.inspectとすると、エラーの内容を確認することができる。ドットインストールでやってた。
#<ActiveModel::Errors:0x007fd1635c5b48 @base=#<Project id: nil, title: "", created_at: nil, updated_at: nil>, @messages={:title=>["can't be blank"]}>
で、こんなエラーが出たので、@messagesの内容を拾ってもっともらしいエラーを表示させよう、と。
      = @project.errors.messages[:title][0] 
:titleの0番目の要素なのでこんな書き方をするみたいだけど、[0]を外してみたら["can't be blank"] と表示された。よくわからない。

 ちなみに、独自のエラーメッセージを表示させる場合には、モデル/app/models内に書くことで可能。
class Project < ActiveRecord::Base
validates :title,
 presence: { message: '空はダメ!' },
 length: { minimum: 3, message: '短い!'}
end
 あ、すんません。hamlで書いてます。

rails new OneApp --skip-bundle

 rails newに--skip-bundleをつけると、bundle install作業をスキップしてくれる。以前の環境と変わらなければスキップしても構わない。

member = Member.newの意味

 モデルを扱う際によく出てくるmember = Member.new的な表現はとにかく丸暗記していて意味を理解していなかった。

 変数memberにMemberモデルをnewしてできたインスタンスをセットしている、ということで、短いながらこれまでで一番私に意味を伝えてくれた解説でした。
PrctModel.new(name: 'Suzuka', level_sing: 10, level_dance: 9).save
 こんな風に変数を使わずにMember.newに対して全部いろいろやっちゃってsaveすればいいじゃないかと思ったりしたんですけどね…。
 この役割はcreateメソッドにあると思うし、既存のレコードに値を追加する場合は困りそうですよね。約束事なんでしょうね。なんで?なんで?と思い悩むところではないのかも。

参考:

テーブルのカラムを追加・削除・名前変更する

 モデルのテーブルにカラムを追加する方法が、私の持っている本では素人にわかるように解説してくれていない。素人だからこそ設計なんてめちゃくちゃだし、すぐに必要になるんですが…。
 昨日まではわからなくなるとモデルを新しく作り直していたので、どうすべきか確認しておく。とりあえずscaffoldで適当なMVCを作ってマイグレーション。
$rails g scaffold PrctModel name:string level:integer
$rake db:migrate
 このときのマイグレーションファイルはこんな感じでした。
class CreatePrctModels < ActiveRecord::Migration
  def change
    create_table :prct_models do |t|
      t.string :name
      t.integer :level
      t.timestamps
    end
  end
end
 さて、コンソールから適当にデータを突っ込んでみます。
[14] pry(main)> prct = PrctModel.new(name: 'Suzuka', level: 10)
[15] pry(main)> prct.save
 もしくは、
[17] pry(main)> prct = PrctModel.create(name: 'Suzuka', level: 10)
この辺もずっと前に意味わからず打ち込んでいたけど、慣れというのは恐ろしいもので、説明はまだちゃんとできないけど身体が少しずつ動くようになってきているかも。
 さて、PrctModel.allとかすると正しくレコードが登録されていることが確認できました。
 ここで、levelをlevel_singに変更、カラムlevel_danceを追加してみます。してみますってこの時点でどうやるかわかってないんですが。
 ふふーん。マイグレーションファイルをコマンドで作ればいいみたい。多分コンソール上やマイグレーションファイルを書き換えても操作できちゃうんでしょうけど、今回はスルーしておきます。

 追加は次のコマンド。クラス名としてAddColumn[変更元カラム名]To[テーブル名]、その後に[変更先カラム名]を入れれば良いみたい。Columnは省略できるっぽいけど、一応書いておきます。
$rails g migration AddColumnLevelDanceToPrctModel level_dance:integer
マイグレーションファイルは上のコマンドからいい感じに作ってくれました。
class AddColumnLevelDanceToPrctModel < ActiveRecord::Migration
  def change
    add_column :prct_models, :level_dance, :integer
  end
end
 これでマイグレーションしてコンソールで確認したら、確かにカラムが増えていました。

 カラムの削除は次の通り。モデル名の前置詞がToではなくてFromです。
$rails g migration RemoveColumnLevelFaceFromPrctModel level_face:integer
 こちらもマイグレーションファイルはいい感じに作ってくれますが、:integerとかの変数型はちゃんと記さないとまずそうです。変数型を書かずにマイグレーションファイルを作ったところ、ファイル内で変数型が:stringになっていて、削除後にロールバックすると変数型が:stringになってしまいそう。

 カラム名の変更は下記の通り。
$rails g migration RenameColumnLevelToPrctModel level_sing
class RenameColumnLevelToPrctModel < ActiveRecord::Migration
  def change
  rename_column :prct_models, :level, :level_sing
  end
end

 この、マイグレーションファイル内でテーブル名が複数形になる意味がよくわからない…。(単数形で試したらエラーになった。)

参考:
【Rails】migrationのchangeとup/downって何が違うの?

2014年7月12日土曜日

サイトを画面の中央に配置する

 ほんとすいません。超初心者で。
 サイト全体をモニタの左右中央に配置したいと思ったのにどうしたらいいかわからず。

 Railsを覚えろと言われたもんだから頑張ってテキストをこなしたりはしていますが、ちょいちょいhtml、css、rubyといったrailsユーザーなら一通りわかっているはずのところで詰まっています。

 ところで、bodyタグに対してなんか設定するんだろうと思っていろいろしていたのですができず、div等にmarginでしようと思ってもcenterとか指定できないみたいだし、なんなんだよーと。
 ググったらすぐわかりまして、例えばdivに下記のようにmarginをauto設定すれば良かったみたい。
<div style="margin: 0 auto;">
なんだよ、autoって。他はみんなcenterじゃないか。

2014年7月11日金曜日

deviseでの認証

 テキストでOAuthとかいうやつでTwitterを使った認証をやったのですが、外からdeviseを使ってみやがれという話がありまして、やってみます。

 とりあえずトップページだけのアプリケーションを作ってログイン認証だけ実装してみます。

参考:
devise使ってユーザー認証機能の追加と設定

 実装してみますというか、上のサイトをとにかく上からそっくりなぞったらそれらしいものができました。すごいですね。メールアドレスとパスワードによるサインアップとサインイン、サインアウトまでが簡単に動くようになりました。
 でも、作業は簡単でも本質はあまりわかっていない。
 まぁでも、ここにサインインしているか確認しながらコンテンツの表示とかを変えていけばそれらしくなるんでしょうかね。

 まともに扱えるようになるんかなーー。

のに子博士のブラボーRuby道

 頭悪くて、クラス作ってメソッド作って、それを利用するときになんでnewする必要があるのかずっとわからなくて、やっぱりコード書く以外に勉強方法はないんでしょうね。とにかく必死でRailsのテキストをなぞってきましたけど、あまりに基本がなっていないとどうしようもないことがようやくわかりました。

 図書館ですでに絶版らしい「のに子博士のブラボーRuby道 プログラミングはじめるゾ」という本を読んだのですが、へったくそな(失礼)漫画とともにほぼ専門用語を使わずにこの辺りの説明をしてくれていまして、これで初めてRailsのテキストの読める状態になったのではないかと思います。
 配列やハッシュとかの概念も前よりもすっきりしたような気がします。


 著者ののに子さんへのお礼に本を買ってあげたいくらいなのですが絶版で、しかも他に著作が無いようで困りました。記念に古本ででも買おうかな。
 あ、と思ったら本名が清水美樹さんという女性の方でした。でも最近はRuby/Rails関連書籍は出されていない様子。残念。

2014年7月10日木曜日

scaffoldとモデル名の関係

 scaffoldに複数形の引数(モデル名)を突っ込むとどうなるのか試した。別になんてことは無いけど気になって。
 まずはeggと単数形で。
~/work/meishi$rails g scaffold egg sex:integer
      invoke  active_record
      create    db/migrate/20140710062006_create_eggs.rb
      create    app/models/egg.rb
      invoke  resource_route
       route    resources :eggs
      invoke  scaffold_controller
      create    app/controllers/eggs_controller.rb
      invoke    haml
      create      app/views/eggs
      create      app/views/eggs/index.html.haml
      create      app/views/eggs/edit.html.haml
      create      app/views/eggs/show.html.haml
      create      app/views/eggs/new.html.haml
      create      app/views/eggs/_form.html.haml
      invoke    helper
      create      app/helpers/eggs_helper.rb
      invoke    jbuilder
      create      app/views/eggs/index.json.jbuilder
      create      app/views/eggs/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/eggs.js.coffee
      invoke    scss
      create      app/assets/stylesheets/eggs.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

 次は複数形eggs。
~/work/meishi$rails g scaffold eggs sex:integer
Plural version of the model detected, using singularized version. Override with --force-plural.
      invoke  active_record
      create    db/migrate/20140710062649_create_eggs.rb
      create    app/models/egg.rb
      invoke  resource_route
       route    resources :eggs
      invoke  scaffold_controller
      create    app/controllers/eggs_controller.rb
      invoke    haml
      create      app/views/eggs
      create      app/views/eggs/index.html.haml
      create      app/views/eggs/edit.html.haml
      create      app/views/eggs/show.html.haml
      create      app/views/eggs/new.html.haml
      create      app/views/eggs/_form.html.haml
      invoke    helper
      create      app/helpers/eggs_helper.rb
      invoke    jbuilder
      create      app/views/eggs/index.json.jbuilder
      create      app/views/eggs/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/eggs.js.coffee
      invoke    scss
      create      app/assets/stylesheets/eggs.css.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.css.scss
 結果は同じでした。でも、複数形の場合は、モデルのテーブル名が複数形なのはおかしいから直したよ的なメッセージが入っています。オプション入れればこの辺りは強制的に指定できるみたい。

 コントローラのみの場合は下記の通りどちらでも指定通りに作られました。
~/work/meishi$rails g controller egg show
      create  app/controllers/egg_controller.rb
       route  get 'egg/show'
      invoke  haml
      create    app/views/egg
      create    app/views/egg/show.html.haml
      invoke  helper
      create    app/helpers/egg_helper.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/egg.js.coffee
      invoke    scss
      create      app/assets/stylesheets/egg.css.scss
~/work/meishi$rails g controller eggs show
      create  app/controllers/eggs_controller.rb
       route  get 'eggs/show'
      invoke  haml
      create    app/views/eggs
      create    app/views/eggs/show.html.haml
      invoke  helper
      create    app/helpers/eggs_helper.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/eggs.js.coffee
      invoke    scss
      create      app/assets/stylesheets/eggs.css.scss

 モデルの場合も、モデル単独でのgenerateでは指示通りに作られました。
~/work/meishi$rails g model egg sex:integer
      invoke  active_record
      create    db/migrate/20140710064223_create_eggs.rb
      create    app/models/egg.rb
~/work/meishi$rails g model eggs sex:integer
      invoke  active_record
      create    db/migrate/20140710064003_create_eggs.rb
      create    app/models/eggs.rb
 コントローラ名はモデルと一緒に使われる場合は複数形。モデルを伴わない場合は単数。
 モデル名はテーブルの名前でもあるから、これ自体は基本的に単数。
 scaffoldは上を両方とも同時に作るんだけど、引数としては単数が普通。必要な部分は勝手に複数形になる。

 ふーん。

 あ、本当はモデル名は大文字で書き始めないといけないんだっけ。単語が複数の場合はStampCollectionとか。くっつけて。そうじゃないとアンダースコア付きのファイル名で生成されない。まぁ、次から気をつけます。

git pushした後にcommit --amendしてpushしてみた

 コミット時のコメントを間違ってしまったのにpushしてしまって、amendしてもう一回pushしたらrejectされた。まぁ、当然ですよね。
~/work/awesome_events$git push
To https://github.com/xxx/awesome_events.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/xxx/awesome_events.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
~/work/awesome_events$gi pull
-bash: gi: command not found
~/work/awesome_events$git pull
Merge made by the 'recursive' strategy.
~/work/awesome_events$
別に何か対処した訳でもなく、あんたのブランチが古いからgit pullしてみろ、とヒントが書かれているので言う通り実行すると、 再帰的にマージしといたよというメッセージ。
 その後pushできましたが、誤ったコミット、修正後のコミット、そのときに自動で発生したマージ処理についてMerge branch 'master' of https://github.com/xxx/awesome_eventsというコメントとともにコミットが追加されていました。

 あぁ、こうなっちゃうのね。意図したこととは違ったけど、データが壊れていないのでよしとする。でも誤ったコメントが入ったままなのは今後なんとかしないと。

BABYMETAL その4

 えーっと、結局のところSU-METALというか中元すず香が好きなんじゃないかというところに思い当りまして。例えばBABYMETALが解散しても中元すず香が歌うならそれを見たいと思うだろうと思うのです。

 そこで、ファン歴2か月のにわか野郎がYoutubeから厳選して歌手活動の足跡を辿ってみたいと思います。主に自分のために。
 いきなり1~2曲目から目頭が熱くなり始めます。最後の方はさくら学院の卒業直前みたいですが、なんかね、当時を知らないけど無感情には見ていられないです。

 まずは9歳。まだ頑張ってレッスンを受けたとおりに上手に歌おうとしているように見えます。


 この時にはなんかもう開眼している感じ。誰かのアドバイスなのか本人の感性なのかわからないけど、上手さを取り違えて癖のある歌い方をしてしまう歌手の多い中でこれだけストレートな声を聴かせてくれる子は珍しい。すでに完成していて、現在のSU-METALとそう変わりません。幼いけど。


 次はアニメの主題歌を歌ったとき。これ素敵。セルフカバーしてほしい。武藤彩未さんとの再結成も歓迎します。
 動画が年代的に前後しているかもしれませんが、お許しを。


 このミュージカルでの歌唱は非常にレベル高い。震えます。ミュージカル女優なんていいんじゃないでしょうか。いや、やっぱり歌を聴かせるアイドルだな。岩崎宏美クラスかどうかはわからないけど、本格派と言っても差し支えないレベルでしょう。


 ほら、卒業式が近づいてきましたよ。この頃にはもうBABYMETALと同時進行始まってるのかな。


 さくら学院の卒業式。みんな泣いちゃってるからね。ずるいよね。泣くよね。


 さくら学院最後のヘドバンギャー!!。その後のライブを含めてもはじけっぷりは一番かもしれません。


 この辺りを踏まえての、BABYMETALです。というかSU-METALです。というか中元すず香です。
 ちなみに、YUIMETALとMOAMETALについては、最初この子たちいらないんじゃないの?というくらいから入った方が後々楽しめます。

 あー、やばいやばい。目から汗が。BABYMETALのおそらく長くはないであろう儚い活動期間を考えてもまた汗が。
 今はその後の未来を勝手に予想するのがとても楽しいです。武藤彩未さんとアイドル対決とか。さくら学院高等部を発足とか。ありそうで怖いんだけど、早めの結婚、引退とかでも伝説になりますね。うたのお姉さんとかも個人的にはありなんですけど。

2014年7月9日水曜日

記号・演算子の意味

 Railsのテキストに何の説明も無く知らない記号の論理演算子が出てきて困ります。&&とか||とか。
 また、わかる人にしかわからない書き方をしているサイトも多い中、下記はいろいろ参考になります。自分がわかる説明をしているページだけをGoogleが表示してくれればいいのに。検索ツールに難易度のパラメータも入れさせてほしい。

参考:
Rubyで使われる記号の意味(正規表現の複雑な記号は除く)

6-6 イベントの編集・削除機能を作る

 イベントの編集・削除機能とそれに関連するリンクを作成する。

  • イベント詳細ページに編集リンクを追加
  • 編集をクリックすると編集フォームに移る
  • 間違った入力にはエラーを表示する
  • 正しく入力されていると更新
  • イベント削除のリンクを追加
  • イベント作成者にだけ表示する
  • 削除をクリックすると確認ダイアログが出て、OKすると削除される

イベント編集機能を作る

まず編集ボタン。event/show.html.erbにp197の通り追記。
   <% if @event.created_by?(current_user) %>
   <% link_to 'イベントを編集する', edit_event_path(@event), class: 'btn btn-info btn-lg btn-block' %>
  <% end %>
 特に上の部分で、イベント作成者にのみ編集ボタンを表示させている。created_by?についてはEventクラスmodels/event.rbで定義する。
  def created_by?(user)
  return false unless user
  owner_id == user.owner_id
  end
 こんなのを追記しましたが、内容がイマイチわからない。
 returnの行でuserが空ならfalseを戻り値にして返す。
unless user
  return false
end
と同じ意味みたい。
 owner_id〜では、イベント作者のowner_idとログインユーザーのowner_idが同じかをチェックしている?演算子の説明とかちょっとだけしてほしい。辛い。

 EventsControllerにedit/updateアクションを追加。
  def edit
    @event = current_user.created_events.find(params[:id])
  end
  def update
    @event = current_user.created_events.find(params[:id])
    if @event.update(event_params)
      redirect_to @event, notice: '更新しました'
    else
      render :edit
    end
  end
 編集時に問題があると編集ページがリロードされちゃうのかな?

未完。

6-5 イベントの閲覧機能を作る

 今度は下記を実装。
  • イベント登録後、イベント詳細ページに移る
  • トップページに未開催のイベントを表示する
  • イベント一覧から詳細ページに移れる

イベント詳細ページの作成

before_action :authenticate, except: :show
def show
@event = Event.find(params[:id])
end
まずはこれだけEventコントローラに追加した。:idの入ったurlからこれを引数として持てこれる。ルーティングはresourcesでOKと。
 イベント詳細ページはログインしていなくても確認できるようにするため、before_actionにexcept: :showを追記してログイン状態をチェックしないようにしている。
 ビューにはイベント内容と、作成ユーザーを表示します。p193の通りファイル作成。
 models/event.rbに下記を追記。
  belongs_to :owner, class_name: 'User'
 ownerについては後で設定するらしい。だからきっとここでのhas_manyの
設定も後回し。
 これでイベント内容が表示されるというけど・・・あ、表示された。すごい。Twitterで使っているIDとプロフィール画像も表示された。なんか楽しい。
 それにしても、ビューを書くセンスってhtmlとcss知っていることが前提っぽいからつらいなー。そこもRubyも知らないのに、Railsって相当誤った選択じゃないか。進めた奴を恨むよ。

イベント一覧ページの作成

トップページにイベント一覧を表示させる。なんか久しぶりにトップページにきました。welcome/index.html.erbを下記の通り書き換え。
<div class="page-header">
  <h1>イベント一覧</h1>
</div>
<div class="list-group">
  <% @event.each do |event| %>
    <%= link_to(event, class: 'list-group-item') do %>
      <h4 class="list-group-item-heading">
        <%= event.name %>
      </h4>
      <p class="list-group-item-text">
        <%= event.start_time.strftime('%Y/&m/%d %H:%M') %> - <%= event.end_time.strftime('%Y/&m/%d %H:%M') %>
      </p>
    <% end %>
  <% end %>
</div>
 @eventについて未定義なので取得処理の実装をする。未開催のイベントを開催時間の昇順で取得する。設定はwelcomeコントローラ。
class WelcomeController < ApplicationController
  def index
  @event = Event.where('start_time > ?', Time.zone.now).order(:start_time)
  end
end
 whereとかorderとかってsqlのクエリでさーね。なんとなくわかるけど詳しい書式がわからん。

参考:

 こんなか。
 お、トップページに一覧が出た。BootStrapって便利そうだな。前にも書いたっけ。無いセンスでCSS一生懸命作るより、用意されたものを組み合わせる方が素人には嬉しいね。参考にできるサイトもたくさんありそう。

参考:

selfの役割

 railsのselfというのがようわからん。
 結局はselfがあるとクラスメソッドとして、無ければインスタンスメソッドとして定義できるみたいな話なんだけど、この手の話って多いすね。もっと明確にdefにインスタンスです!とか書けた方がいいんじゃないのかね。素人考えですが。

参考:
modelクラスの中でのselfの使い方

2014年7月5日土曜日

6-4 イベントの登録機能を作る

 わからないながら、ずっとメモし続けていたら話が少し見えるようになってきた気がする。メモを簡略化して、メモにかける時間を少し短くしようと思います。

 ここでやりたいこと。

  • ヘッダーにイベント作成リンクを設置。
  • ログイン状態で押すとイベント登録フォームへ移る。
  • 未ログインならトップページへリダイレクト。(これなんか親切じゃないね。)
  • イベント登録で誤った入力があるとエラー表示。
  • 正しければ登録処理。

タイムゾーンを設定する

デフォルトではUTC(協定世界時)に設定されているため、config/application.rbでコメントアウトされているタイムゾーンの設定をTokyoに変更します。こうしないと、イベントの登録時間等が登録者の意図しない時間になってしまう。
    config.time_zone = 'Tokyo'

イベント用のモデルを作成する

rails g resource event owner_id:integer name:string place:string start_time:datetime end_time:datetime content:text
  む。rails g resourceは初めて見ました。モデルとコントローラとルーティングを同時に作成するのか。ビューのhtmlファイルとかは作らないみたい。

参考:
[Ruby][Rails] Railsのgenerate scaffoldとgenerate resource

 マイグレーションファイルを修正してNOT NULL制約とインデックスを追加。このインデックスってのはなんなの?って今頃聞いちゃいけないこと?
 つーかマイグレーションつーのが未だにボンヤリしてるな。もっかい説明読めばイメージつかめるかな。

 今回は文字数制限等をvalidationで決めるって。NOT NULL制約はここに書いちゃ行けないの?ここにもpresence: trueとか書いてるじゃん。両方あれば間違いないとかそんなことかい?ググるとマイグレーションファイルは触っていない人も多い様子。
 validationはapp/models以下、event.rbで設定。
class Event < ActiveRecord::Base
validates :name, length: { maximum: 50 }, presence: true
validates :place, length: { maximum: 100 }, presence: true
validates :content, length: { maximum: 2000 }, presence: true
validates :start_time, presence: true
validates :end_time, presence: true
validate :start_time_should_be_before_end_time
private
def start_time_should_be_before_end_time
return unless start_time && end_time
if start_time >= end_time
errors.add(:start_time, 'は終了時間よりも前に設定してください')
end
end
end
 あれ?validateって検査の定義とかするんだっけ?いいのかな。開始時間が終了時間の前にちゃんと設定されているかどうかチェックするんだな。

参考:

 合わせてビューにもイベント作成のリンクを追加。リンク先のnew_event_pathはrails g resourceと同時にルーティングが追加されているので何もしなくて良い。確かにあった。

ログイン状態を管理する処理を作る

 複数のコントローラで利用する汎用的な処理は、一般的にApplicationControllerに書くそうです。そうですって、まぁ、そうでしょうね。感覚としてはわかります。でも本見ずに進めていたら、思考停止しちゃうかもしれない。
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user, :logged_in?
  private
  def current_user
  return unless session[:user_id]
  @current_user ||= User.find(session[:user_id])
  end
  def logged_in?
  !!session[:user_id]
  end
  def authenticate
  return if logged_in?
  redirect_to root_path, alert: 'ログインしてください'
  end
end
 application_controller.rbをこんな風に書き換えろとまず言われたんだけど、||=ってなに?ググったら、左辺の変数が偽か未定義の場合に右辺の値を代入する、だって。ふーん。初めて変数使うときはいつでもこうするべきなのかね。説明してよ。=だけだとなんか不都合あるんだろうか。

参考:

 authenticateのアラートを表示させるためにレイアウトも修正。コードは前後省略。
 <div class="container">
  <% if flash[:notice] %>
  <div class="alert alert-success">
  <%= flash[:notice] %>
  </div>
  <% end %>
      <% if flash[:alert] %>
        <div class="alert alert-danger">
        <%= flash[:alert] %>
        </div>
      <% end %>
  <%= yield %>
 </div>
 まただ。このflashって変数、なんだよ…。

参考:

 説明読んでもイマイチ。flash無しではダメ?前のデータが残っちゃうからか。そういうことかな。
 続いて、authenticateメソッドをEventsControllerに対して設定する。そろそろわかんなくなってきたぞ。
 authenticateをbefore_actionに設定して、未ログインユーザーがEventsControllerのアクションにアクセスしたとき、トップページにリダイレクトする。と打ち込んで3回くらい読む。
 ログインユーザーだけしかアクセスできないアクションにアクセスがあった場合には、そのアクションを起こす前にユーザーがログインしているかチェックするわけだね。未ログインならトップページに飛ばす。やっとかよ。これの理解に何分もかかっちゃうのかよ。
 今日はただでさえ頭痛が酷いのに、そこへこういったテキストを読むなんて馬鹿げているけど、気が焦ってしまって仕方ない。最近気になり始めた武藤彩未さんのアルバムでも小音量で聴いて癒されようかな。つーかBABYMETALのファンになったら次から次へと関連アイドルの知識が耳に入ってくるので困る。

 events_controller.rbについては以下の通り。
class EventsController < ApplicationController
  before_action :authenticate
  def new
  @event = current_user.created_events.build
  end
  def create
  @event = current_user.created_events.build(event_params)
  if @event.save
  redirect_to @event, notice: '作成しました'
  else
  render :new
  end
  end
  private
  def event_params
  params.require(:event).permit(
  :name, :place, :content, :start_time, :end_time
  )
  end
end
 newとcreateアクションではapplication_controllerに追加したcurrent_userメソッドを使ってログインユーザーを取得している。んー。んー。わかんね。
 あとは、ここで出てきたcreated_eventsをmodel/user.rbで定義します。
class User < ActiveRecord::Base
has_many :created_events, class_name: 'Event', foreign_key: :owner_id
以下略
 またこの項は何度も読み直す必要がありそうだな。日本語が読めていないのか、説明が悪いのか。いや、一応ベストセラーらしいし、原因は自分だよな。多分。

イベント登録用のフォームを作る

 次はイベント登録用フォームを作る。events/new.html.erbを新規作成。はい作った。
<% now = Time.zone.now %>
<div class="page-header">
<h1>イベント作成</h1>
</div>
<%= form_for(@event, class: 'form-horizontal', role: 'form') do |f| %>
<% if @event.errors.any? %>
 <div class="alert alert-danger">
  <ul>
  <% @event.errors.full_messages.each do |msg| %>
   <li><%= msg %></li>
  <% end %>
  </ul>
 </div>
<% end %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :place %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :start_time %>
<div>
<%= f.datetime_select :start_time, start_year: now.year, end_year: now.year + 1 %>
</div>
</div>
<div class="form-group">
<%= f.label :end_time %>
<div>
<%= f.datetime_select :end_time, start_year: now.year, end_year: now.year + 1 %>
</div>
</div>
<div class="form-group">
<%= f.label :content %>
<%= f.text_area :content, class: 'form-control', row: 10 %>
</div>
  <%= f.submit '作成', class: 'btn btn-default', data: { disable_with: '作成中…' } %>
<% end %>
 で、随分いろいろ打ち込みましたが、名前/場所/開始時間/終了時間/内容の入力フォームとイベント作成ボタンを作っています。
 ここで実際にブラウザで動作を確認したら打ち間違いによるエラーが死ぬほど出て死んだ。数時間かけてやっと原因がわかってげんなり。
 入力フォームが出るようにはなったけど、登録するとPlace can't be blankとか言われるな。空欄ではないんだけど…。
 再度ハマって、更に打ち間違いとコピペミスがあって、マイグレーションし直したりしてなんとかなった。酷いなオレ…。

i18nの設定をする

 なんすか、i18nって。ラベルとエラーの修正、ですか。ラベルやvalidationのエラーを日本語にしようよ、ということみたい。
 設定はconfig/spplication.rb。以下の部分をコメントアウトして、最後の右辺を:deから:jaに書き換える。
config.i18n.default_locale = :ja
汎用のエラー辞書データはrails-i18nのリポジトリにまとめられている。下記からダウンロード。
~/work/awesome_events$curl -o config/locales/ja.yml -L https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml
以下はファイルの内容の一部。へーほー。
  errors:
    format: ! '%{attribute}%{message}'
    messages:
      accepted: を受諾してください。
      blank: を入力してください。
      present: は入力しないでください。
      confirmation: と%{attribute}の入力が一致しません。
      empty: を入力してください。
      equal_to: は%{count}にしてください。
      even: は偶数にしてください。
      exclusion: は予約されています。
  更に、同じくconfig/localesに、ar-ja.ymlとして今回のアプリ向けの辞書データを作ります。よく書式がわからないけど、スルーしとこうかな。
ja:
  acriverecord:
    models:
      event: イベント
    attributes:
      event:
        name: 名前
        place: 場所
        start_time: 開始時間
        end_time: 終了時間
        content: 内容
  あ、確かにエラーが日本語で表示される。

6-3 OAuthを利用して "Twitterでログイン" 機能を作る

OAuthとは

OAuthは、Twitter等の大手サービスを利用する認証方法。利用するサービスのパスワードを又貸しするようなことをせずに認証を実現できるので、手軽で現在は広く使われているんですってよ、奥さん。

Twitterアプリケーションの登録

p168に沿ってその通り登録。Application detailsのNameは重複が許されないとのことで、適当にふざけた名前を付けた。

Twitterアカウントでログインする機能の作成

とりあえず以下がやりたい。
ヘッダーにログインリンクを作る
クリックするとTwitter認証画面
Twitter認証画面で適切なユーザー名とパスワードの入力でログイン
ログイン中はログインリンクの代わりにログアウトのリンク
ログアウトをクリックするとログアウトする
認証に実際に使用するgemはOmniAuth。Twitterを認証に利用する場合は更にOmniAuth Twitterというgemが必要。
 今回はテキストに合わせるため、バージョンをpatchレベル以外は固定。ポリシーはアプリケーションにより決める。

 次にTwitter管理画面上のAPI keyとAPI secretをOmniAuthに設定する。Rails4.1からはconfig/secrets.ymlが設定ファイル。
default_twitter: &default_twitter
  twitter_api_key: 'tjEBXXXXXXXXXXXXXdjhBo'
  twitter_api_secret: 'mZKR0XXXXXXXXXXXXXXXXXXXXXX45e4fyO73nt'
development:
  secret_key_base: tjEBZXXXXXXXXXXXX4djhBo
  <<: *default_twitter
test:
  secret_key_base: mZKR0vXXXXXXXXXXXXXXXXXXu9t45e4fyO73nt
  <<: *default_twitter
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  twitter_api_key: <%= ENV["TWITTER_CONSUMER_KEY"] %>
  twitter_api_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %>
 次、もう一つ。config/initializers/omniauth.rbを作成して下記を入れておく。
Rails.application.config.middleware.use OmniAuth::Builder do |
provider :twitter,
 Rails.application.secrets.twitter_api_key,
 Rails.application.secrets.twitter_api_secret|
end
  これで設定完成。説明はp173を参照。まだこのキーがいつどのように使われるかよくわかっていない。

 続いてログインユーザーのモデルを作成する。
rails g model user provider:string uid:string nickname:string image_url:string
マイグレーションファイルにNOT NULL制約とユニークインデックス追加しておく。これはなんだ。validationじゃなくて、ここに書くんだ。うーん。ちょっとわからんぞ。なんにしても、未記入は許しまへんで、ということですよね?
      t.string :provider, null: false
      t.string :uid, null: false
      t.string :nickname, null: false
      t.string :image_url, null: false
参考:

 で、マイグレーションする、と。

 続いては、Twiterにログインというリンクを作る。コードはp175を参照して、application.html.erbに書いた。認証先のリンクはOmniAuthの仕様で、/auth/:providerになる。
 この後サイトへアクセスしてログインボタンを押すと、見慣れたTwitterの「連携アプリの認証」ボタンの画面に移った。おー、なんか今っぽいすね。
 認証ボタンを押すと、まだ後処理が用意されていないためエラーになりました。ルーティングエラー。

 さて、ログイン兼ユーザー登録用のコントローラを作成します。
rails g controller sessions
 この辺のコントローラの名前とか、自分にセンスがなさそうなので心配。単数系にするときとかもどうもぼんやり。今回はユーザーを扱うので当然複数形ですよね。こういう単純な考え方がそもそもいけないのか。

 createアクションの作成。
class SessionsController < ApplicationController
def create
user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])
session[:user_id] = user.user_id
redirect_to root_path, notice: 'ログインしました'
end
end
OmniAuthによりrequest.env['omniauth.auth']にHashに似たOmniAuth::AuthHashが格納される。Twitterから渡されたユーザー情報やOAuthのアクセストークンも含まれる。
 find_or_create_from_auth_hashはまだ未定義。方針としては、引数に関連するユーザーがいればそれを返し、いなければ新規作成して返すという動きをさせる。
 最終的にはUser.find_or_create_from_auth_hashが返すUserのIDをセッションに格納することでログインしたという扱いにする。こういうの難しいわ〜。論理的に説明だけされるとボーッとなりますね。ちょいちょい具体的な話や面白話がないと。本が何倍にもなりそうですが。
 当然次はUser.find_or_create_from_auth_hashの実装。/models/user.rbで。
class User < ActiveRecord::Base
def self.find_or_create_from_auth_hash(auth_hash)
provider = auth_hash[:provider]
uid = auth_hash[:uid]
nickname = auth_hash[:info][:nickname]
image_url = auth_hash[:info][:image]
User.find_or_create_by(provider: provider, uid: uid) do |user|
user.nickname = nickname
user.image_url = image_url
end
end
end
 find_or_create_byはActiveRecordのメソッド。
 内容としては、引数で渡したproviderとuidを持つレコードが存在していればそのオブジェクトを返し、存在しなければprovider、uid、nickname、image_urlを設定してレコードを作成し、そのオブジェクトを返す、と。

 ルーティングの追加。
get '/auth/:provider/callback' => 'session#create'
  これはどういうことだ。/auth/:provider/callbackで帰ってくるってのは自明?あ、さっき出たルーティングエラーにアクセス先が/auth/twitter/callbackとは書かれているな。OAuthとやらの仕様か。それともTwitterの仕様?
 application.html.erbについてもp179の通り追記する。これでcreateアクションからの返り値により、ログインしましたというメッセージが表示されるようになる。できた。

 最後はログアウト処理。まずはdestroyアクションの追加。
def destroy
reset_session
redirect_to root_path, notice: 'ログアウトしました'
end
 次は、ログイン中は画面右上にログアウトのリンクを表示させたい。logged_in?メソッドを定義して、ログイン状態が把握できるようにする。
 application.html.erbではp180の通りlogged_in?の条件分岐でログイン/ログアウトを表示し分ける。ログアウトのリンク先のlogout_pathはあとでroutes.rbで設定する。
 logged_in?の定義はapplication_controller.rbで下記の通り。
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :logged?
  private
  def logged_in?
  !!session[:user_id]
  end
end
 hyper_methodってなんだよ。コントローラのメソッドをビューでも使う場合に使うってよくわからない。

参考:

 あと、!!ってなに?基本過ぎ?

参考:

 はぁ、!が論理演算のnotだって。すると、sessionがユーザーidを持っていれば!によってfalse、もう一つの!でtrue、で結果としてこれがログイン状態になるんだ。頭いいねぇ。感心した。
 未ログインでsessionがnullなら!でtrue、もう一回!でfalse。だから未ログイン。

 最後にルーティングを追加。
 get '/logout' => 'sessions#destroy', as: :logout
 プログラミングでごく一般的なことがわかっていないから、どの説明も本筋から外れたところで新たな発見がたくさんある。ありすぎて調べ続けているとなにやっていたかわからなくなったりする。

 この深夜に仕事のLineがきて、確かに自分が悪いところもあるけどものすごく不快な気持ちになってしまった。寝よう寝よう。

2014年7月4日金曜日

railsコマンドが動作しない

 ググるとspring周辺が悪さをしているみたいなことが事例としてたくさんあって、あれこれやっても直らず、先に結論を申し上げますとMacのFinderのマイファイルからファイルをいくらか消していましてね、それが原因でした。Macを知らない私が原因でした。
 FinderでUndoできたのでことなきを経ましたが、これはなかなか大変なことです。今始めていたプロジェクトはgithubで管理もしていませんでしたので。結構サイテーなことだとは思います。

 まぁ、でもよかった。直って。

 マイファイルって、Windowsで言うライブラリフォルダみたいなもんでしょうかね。ややこしいですね。

 68020くらいの頃はMacとはお友達だったはずなんだけど、仕事ではろくなことが無い。

Gemfileでのバージョン管理

 gemのバージョンはGemfileへ厳密に書くことで固定、管理が可能。

 書式は下記で確認。

 バージョンのX.X.Xは、メジャー.マイナー.パッチと呼ばれる。

参考:
Gemfile

6-2 アプリケーションの作成と下準備

rails newでアプリケーションの作成

テキストではrails4.1.1を使うので、インストールされていなければする。されていればプロジェクト作成時にバージョンを指定して作成する。
 -Tは--skip-test-unitと同意。RSpecを使うのでtest::unitを組み込まない。プロジェクトのルートディレクトリに移ってrails sで一応サーバーの動作を確認。
rails -v
gem list rails
gem i -v 4.1.1 rails
rails new awesome_events -T
rails _4.1.1_ new awesome_events -T
rails s

独自のトップページを表示してみる

  welcomeコントローラとindexアクションを作成する。
rails g controller welcome index
また、トップページへのアクセスをこのindexへのルーティングをroutes.rbに書いておく。route.rb変更した後はサーバーWEBrickを再起動する。
root to: 'welcome#index'

Bootstrapを導入

CSSはTwitter Bootstrapを利用。ダウンロード後、vendor/assets内に展開する。今回使うのは以下のcss、jsの2ファイルだけみたい。
bootstrap.min.css
bootstrap.min.js
Assets Pipelineにこの二つを含めるためにapp/assetsの設定にパスを追加する。〜/assetsにはパスが通ってる?からファイル名だけでいいみたい。ちなみに拡張子はいらない。
#app/assets/stylesheets/application.css
*= require bootstrap.min
#app/assets/javascripts/application.js
//= require bootstrap.min
application.html.erbをp167のように書き換えてブラウザでチェック。できた。

 Bootstrapってすごいね。この手のテンプレートっていろいろあるんでしょうけど、結構事務的なサイトの構築であればデザイナーっていらなくなっちゃったりしそう。

 ここまでとりあえず疑問点は無かった。

6-1 イベント告知アプリケーションを作る

 ようやく、具体例を持ってRailsの機能をどのように使うか見てみましょう、ときました。

実装する主な仕様

詳しくはp160。

  • ユーザーは作成されたイベント情報を閲覧することができる
  • Twitterアカウントでログインできる。
  • ログインユーザーだけがイベントを作成できる
  • 自分の作成したイベントだけ削除ができる
  • ログインユーザーは誰の作成したイベントにも参加できる
  • ログインユーザーは退会することができる
  • 退会したユーザーの情報は削除される
  • 退会したユーザーの作成したイベントは残る
  • イベント作成者・参加者が退会している場合はユーザー情報として「退会したユーザーです」と表示する

 ルーティングの方針はp161。ユーザー作成、ログイン(auth)、ログアウト(logout)、イベントCRUD(event)、ユーザー情報(user)、退会処理あたりを作ることになりそう。

5-6 rails-erdでモデルのER図を生成する

 もー、ER図ってなんだよ!

参考:
実体関連モデル

 そういうことですか。データベースのデータモデルを図として関連性をまとめたものらしい。
 で、rails-erdでは実際に構築されているdbをER図化できるそうな。すごいね。

 Gemfileにrails-erdを追加すると、rakeタスクとしてerdが追加されPDFとしてER図が出力できるようになる。でも裏でGraphvizという秒がツールを使うので、別途インストールが必要。自動化しろって!
 /usr/local$brew install graphviz
Error: You must `brew link libpng' before graphviz can be installed
Warning: It appears you have MacPorts or Fink installed.
Software installed with other package managers causes known problems for
Homebrew. If a formula fails to build, uninstall MacPorts/Fink and try again.
/usr/local$brew link libpng
Linking /usr/local/Cellar/libpng/1.6.10...
Error: Could not symlink include/libpng16
/usr/local/include is not writable.
エラーが出て言われた通りのコマンドを打って、最終的に書き込めない、権限が無い、と言われてしまった。/usr/local/includeの所有者はrootで、自分にはreadしかできない模様。この借りている呪われたMacのせいか。
 結果を見たかったけど、rootのパスワード知らないし、とりあえずここはパス。 あとで確認しよう。

---

 とりあえずgraphvizはインストーラをダウンロードしてなんとかした。
 rake erdするだけで簡単にモデル相関図が生成されるようになり、モデル設計にはいろいろ役に立ちそう。自分で考えるときも、複数人であれこれ突っつくのにも良さそうです。
rake erd attributes=foreign_keys,primary_keys,timestamps,inheritance,content
なんてオプションを付けると、省略されていたインデックスとかが省略されずに全部入りで表示できるみたい。

参考:
Rails ERDを試してみた

5-5 Springでコマンドを高速化する

Springとは

railsやrakeコマンドの実行の前処理を2回目以降の実行時に簡略化し、高速化する。Windowsでは使えない。
 Rails4.1ではGemfileに標準実装。確かに入っている。
 この機能を使うには、コマンドの前にspringを入れてあげる。
困ったらspring help。

 テストツールのRSpecをspring上で動かすには、別途spring-commands-rspecをGemfileに追加する必要がある。もうこういうの嫌だ。必要なものなら、自動でインストールしてくれればいいじゃない。

5-4 Better Errorsでエラー画面をよりリッチに表現する

 Better Errorsというgemを入れるとエラーがおり詳細に表示される、と。併せて変数の内容が出力されるbinding_of_callerも入れた方がいいよ、と。
gem 'better_errors', group: [:development, :test]
gem 'binding_of_caller', group: [:development, :test]
サーバー再起動して、例えば存在しないURLにアクセスするとリッチテイストなエラーが表示される。
この場ですぐにREPLな確認作業も可能です。(画面右にコンソールがある。)

5-3 Hirbを使ってコンソール上のモデルの出力を整形する

 毎回新しい言葉が出てくるのね。もう頭がね。頭のキャパがね。若くないんでね。死ぬよ?
 Hirbはコンソール上に表示されるdbの結果を、表形式で表示してくれるそうです。これ、絶対入れないといけないやつじゃないの?Railsだけじゃないと思うけど、標準実装されていて当然と思われるものが実装されていないってのは、らしいというか。Rails全部入り、みたいなのもあるんでしょうかね。
 まぁ、いいか。Gemfileへの追加は以下の2点。
gem 'hirb', group: [:development, :test]
gem 'hirb-unicode', group: [:development, :test]
 あとは、コンソール上でHirb.enableとすればその後コンソール上でのdbの結果は表形式で表示されるそうです。
 あれ?モードが確かにtrueになっているのに表で表示されないよ?
[23] pry(main)> Hirb.enable
=> true
 この説明の後にpryではHirbが使えない、と書いてある。どういうこと。設定が必要なようです。
 Railsプロジェクトのルートに.pryrcとして設定を配置します。設定内容は下記のFAQからコピペしました。
 設定の中でHirb.enableが実行されているので、pry起動時に有効になるようです。

参考:

 あ、できた。下半分がHirbが有効になった状態。 いいじゃない。 


 こんなの標準実装だよ!初心者としてはここに時間とられたくないよ…。

5-2 PryをRailsのコンソールとして利用する

 Pryってなんて読むの?プライでいいらしいよ。irbより高機能なREPLですって!こういう表現嫌い。もう忘れてるから。
 REPLは対話型評価環境だって。Read-eval-print loopなんだって。

 インストールするだけならgem install pryでOKらしいけど、rails console上で使うにはpry-railsをインストールする必要がある。似たようなのいっぱいあるね。

pry-railsでPryを組み込む

gem 'pry-rails', group: [:development, :test]
Gemfileにこれを書いてbundle install。group以降は環境設定。
~/work/gem_sample$rails c
Loading development environment (Rails 4.1.1)
[1] pry(main)>
そうすると、あ、ほんとだ。rails cでpryが起動してきた。

Pryを使ってみる

Pry上ではlsでスコープ内の変数やメソッドの一覧が出る。ふーん。
1] pry(main)> ls
Rails::ConsoleMethods#methods: app  controller  helper  new_session  reload!
self.methods: inspect  to_s
locals: _  __  _dir_  _ex_  _file_  _in_  _out_  _pry_
cdで移動すると、場所によりlsのとる対象が変わる。

Pry-railsで追加されるコマンド

recognaize-path
show-middleware
show-model
show-models
show-routes
この辺。
 show-modelは引数にモデルの名前をとります。
[2] pry(main)> show-model Tweet
Tweet
  id: integer
  body: string
  user_id: integer
  created_at: datetime
  updated_at: datetime
  belongs_to :user

Pryでブレークポイントを設定する

ソースコードにbinding.pryを入れると、プログラムが中断されて、その状態のままコンソールが立ち上がる。exitで次の処理へ進む。

Pryでステップ実行を行う

ステップ実行を行うにはbyebugが必要で、Pryとの連携にはpry-byebugというgemを使う。
gem 'pry-byebug', group: [:development, :test]
 プログラムが中断したところでnextかstepと入力すると次の処理に移る。これで一つずつ処理を追って行ける。なんか便利そう。その他の追加コマンドはhelpで確認できる。


2014年7月3日木曜日

5-1 サンプル用のRailsプロジェクトを用意する

 今さらっと6章を見たら、早くここやりたい!と思って5章飛ばしてやろうかと思ったけど、5章で教えたあれがとか言われると嫌なのでさらっとやる。

 とりあえずここではいくつか良さげなgemを紹介するためにプロジェクトを新しく作れ、と。
rails g scaffold user name:string
rails g model tweet body:string user:references
rake db:create
rake db:migrate
tweetってのが出てきて、なんか実際的な話になりそうでワクワクしますね。ウキウキミッドナイトですね。まじあげぽよでぴかぴかみらーぼーるですね。

4-2 レイヤーを追加するgemの例

モジュールとビューを橋渡しするactive_decorator

 開発の支援をしてくれる、レイヤーを追加するgemがあり、active_decoratorがその一つ。その一つ、なんてよくわかってません。
 とりあえずインストール。
#Gemfile --> gem 'active_decorator'
~/work/book_admin$bundle install
 userをscaffoldで作成してmigrateして、decoratorをオプションにして以下を実行。
rails g decorator user
 app以下にディレクトリとともに/decorators/user_decorator.rbが作成される。
 ここにメソッドを定義すればビューに渡されたモデルオブジェクトだけが呼び出せるようになる。
# coding: utf-8
module UserDecorator
  def email_link(body = nil, &block)
  if block_given?
  link_to("mailto:#{email}", &block)
  else
  link_to(body, "mail_to:#{email}")
  end
  end
end
 例えば上のように定義して、下のような感じでビューで利用する、と。細かな注意点はp137に。
<td><%= user.email_link("Send mail") %></td>
 でも、なんすかね。これっているの?あ、そうかいろんなビューで使い回すってこと?バカみたいな今更の気づき。
 あと、p135〜136にrake g scaffoldって例が載っているけど、これはrails gの誤表記ってことでいいんですよね。

Sidekiq

 WEBアプリケーションで長い時間がかかる処理には、これをバックグランドで継続しつつ非同期処理が必要になる。SidekiqとRedisが必要。(Windowsは非対応。)
sidekiqはgemで、redisはダウンロードしてシステムにインストール。Linuxのディストリビューションによってはパッケージとして用意されているらしい。Macでは用意されていないようなので、下記を参考にした。

参考:

 この処理が必要になることは、今考えているサイトでは無さそうなので、使い方はそのときにp139以降を参考にしよう。

4-1 MVC以外の構成要素の扱い

 MVCもまだ理解しきれていませんがね…。
 アプリケーション内で利用するけどMVCに当てはまらないモジュールをどう扱うか。

  • モデルとして扱う
  • libディレクトリで管理する
  • 新しいレイヤーを定義する

libディレクトリ

libディレクトリには元々requireパスが設定されているので、例えばlib/tatoeba.rbというファイルがあれば、下記でインクルードできる。
require 'tatoeba'
また、libにはtasksというディレクトリがRailsプロジェクト作成とともに作られますが、ここはRakeタスクの置き場所です。ここに.rake拡張子のファイルを置けば、rakeコマンドで直接利用できる。

オートローディング

 Railsでは、クラス名、ファイル名が下記の規約に沿っていれば自動でファイルをrequireしてくれる。
  • ファイル名はスネークケースで記述し、クラス名をキャメルケースで記述する
  • クラスやモジュールのネームスペースはディレクトリで表現する
 例えば、Roll::SuperUserというクラスを参照して、それが定義されていなければroll/super_user.rbをrequireしようとし、autoload_pathsに含まれるディレクトリにも無ければエラーが発生する。
 例えてもらっても2番目の説明がよくわからない。

 autoload_pathsで設定されているデフォルトは下記のディレクトリ。
  • app/controllers
  • app/models
  • app/helpers
  • app/mailers
  • app/controllers/concerns
  • app/models/concerns
 オートローディングさせるディレクトリの追加はconfig/application.rbで行う。詳しくはp132。

新しいレイヤーの配置とオートローディング

 app以下にディレクトリを作成し、autoload_pathsを追加すれば、あとは命名規約に沿っていればそのクラスは他のコード内からすぐに使えるようになる。
 app以外でもいいらしいけど、一般的にapp以下に配置するみたい。

 はー、わかんね。

2014年7月2日水曜日

Railsのコーディング/命名規約

 Railsは規約通りにコード書けば裏でうまいことしてくれるようですが、曖昧なものでないのなら、それこそそこを手助けしてくれるフレームワーク?があってもいいと思うんだけど。
 簡単と思わせておいて、ルールだらけなので後でひも解くのが大変な気がする。

 まぁ、文句はこのくらいにして、その規約が覚えられないのでとりあえずリンクをメモ。
 これまで自分が打ち込んできたもので規約から外れているものがいくつも思い浮かびます。ルーティングとか。センスのかけらもありません。

参考:

 良い例と悪い例が比較できて助かります。今後何度もお世話になりそうです

ページにより読み込むCSSを変える

 Railsのデフォルトでは、CSSはassets/stylesheetsの中を読んでくれるみたいだけど、ページ個別に適用したくて困った。
 いろいろなサイトを見たけどそのままではうまくいかず、下記の手順を踏んだ。

 まずapplication.cssで、assetsの例外を示しておく。下記を追加する。今回の例ではemail.cssが対象。
*= stub email
それから対象のビューのheadに下記を追加。
<%= yield :head %>
= yield :head #haml
 そんで、対象のビューの先頭に以下を突っ込む、と。(表記はhaml。)
-content_for :head do
  = stylesheet_link_tag '/inside/email', media: 'all'
 これでエラーが出て、下記を config/intializers/assets.rbに追記しろと具体的に言われたのでその通りにしたらできました。プリコンパイルって前にやったけどボンヤリしてる…。
Rails.application.config.assets.precompile += %w( inside/email.css )
できましたけど、相当回りくどいことをしていそうな気がする。
 まぁ、気に食わなかったらえらい人が文句言ってくるでしょう。

参考:
Rails4で、IEのみ特定のjsとCSSを読み込ませる。

 html周辺の話は8年くらい前に自分の稚拙なサイトを手作業で更新していたのでなんとなく感覚的にわかります。わかりますというか納得しやすいですね。
 動的、Rubyな要素が入ってくるととたんにわけがわからなくなる。はー。