Hello, Stupid World! -2ページ目

Hello, Stupid World!

いろいろとメモ代わりに書いていきます。

前回、TwitterBootstrapを導入して少し見栄えがよくなりましたが
まだ少し気になる点があるので修正します。



まず、ボタンの文字が黒くなってしまって見えない部分があります。
これは調べてみた所、プロジェクトフォルダのapp\assets\stylesheetsにある
scaffolds.css.scssが原因です。

この中のaタグの指定が効いてしまっているので、これをコメントアウトしておきます。

[scaffolds.css.scss]
/*
 a {
   color: #000;
   &:visited {
     color: #666;
   }
   &:hover {
     color: #fff;
     background-color: #000;
   }
 }
 */

ついでにscssファイルについて説明。
scssファイルはSassというCSSを簡易的に書く言語で使われるファイルです。

SassはCSSを階層的に書くことで同じ指定を省略できたり
計算や変数等使えるようです。
詳しく知りたい方は調べてみて下さい。



修正した結果、文字部分が白くなり見やすくなりました。
次に全体的に中央に寄せるとともにテーブル内も調整してみました。



修正したCSSの内容は以下です。

[index.html.erb]

 <div class="container-fluid">
  <div class="row">
<h1 class="col-md-11 col-md-offset-1">Listing tasks</h1>
</div>
<div class="row">
<div class="table-responsive col-md-10 col-md-offset-1">
<table class="table table-striped">
 <thead class="row">
   <tr>
     <th class="col-md-1">Title</th>
     <th class="col-md-1">Priority</th>
     <th class="col-md-2">Start</th>
     <th class="col-md-2">End</th>
     <th class="col-md-1">Location</th>
     <th class="col-md-1">Person</th>
     <th class="col-md-1">Tag</th>
     <th class="col-md-3"></th>
   </tr>
 </thead>

 <tbody>
   <% @tasks.each do |task| %>
     <tr>
       <td><%= task.title %></td>
       <td><%= task.priority %></td>
       <td><%= task.start %></td>
       <td><%= task.end %></td>
       <td><%= task.location %></td>
       <td><%= task.person %></td>
       <td><%= task.tag %></td>
       <td><%= link_to 'Show', task, :class => 'btn btn-primary' %>
       <%= link_to 'Edit', edit_task_path(task), :class => 'btn btn-primary' %>
       <%= link_to 'Destroy', task, method: :delete, :class => 'btn btn-warning', data:
{ confirm: 'Are you sure?' } %></td>
     </tr>
   <% end %>
 </tbody>
</table>
</div>
<br>
</div>
<div class="row">
<div class="col-md-11 col-md-offset-1">
<%= link_to 'New Task', new_task_path, :class => 'btn btn-primary' %>
</div>
</div>
 </div>

重要部分を緑の文字で表記しました。
それぞれ説明します。

■class="container-fluid"
    領域が画面いっぱいに広がり、中のコンテンツは中央に寄ります。
    似たものにcontanerがあり、どちらも中央寄せになるが、
    画面いっぱいになる点が異なる。

■class="row"
    行。container/container-fluidの中に書く。

■class="col-md-xx"
    列。xx部分が幅を指す。画面を12分割にした値を入れるので
    col-md-1ならば1/12の広さになる。
    col-md-xxはデスクトップPC用。タブレット用のcol-sm-xxや
    携帯用のcol-xs-xxもある。

■class="col-md-offset-xx"
    指定したタグの前に入れるスペースの広さ。
    12分割だったりcol-sm-offset-xx/col-xs-offset-xxがあるのは
    col-md-xxと同じ。

■class="table"
    Bootstrapの表形式を使う場合に指定。
    線が間に引かれたり、見栄えがよくなる。

■class="table-responsive"
    レスポンシブ対応のテーブルにする。
    画面が拡大されてテーブルが入りきらなくなった時にスクロールバーが
    あらわれる。
今回はまた、Railsに戻ります。
前回、Herokuへのアップロードまで行いましたが、今回は画面を
ブラッシュアップしていきます。

Twitter Bootstrap(以下、Bootstrap)を導入する事で簡単に見栄えの
良いものが作れます。

BootstrapとはCSSのスレームワークでデザインに便利な
スタイルやフォント、JavaScript、アイコンが用意されています。
様々なOS(スマフォも)、ブラウザに対応しているので
Bootstrapを使うだけで様々なものに対応できます。

便利な機能としてはグリッドシステム(画面を等分に分割して簡単に
レイアウトできる思想、機能)や画像ファイルを自動で拡大・縮小する
機能などがあります。
勿論、タブなんかも簡単に作れます。

■1.ダウンロード

こちらからダウンロードします。今回は3.3.2
http://getbootstrap.com/getting-started/#download


■2.各種ファイルの移動

ダウンロードが終わったらダウンロードしたファイルを
プロジェクト内の下記の位置に移動します。
dist/css 配下 → vendor/assets/stylesheets
dist/fonts 配下 → vendor/assets/fonts
dist/js 配下 → vendor/assets/javascripts

■3.各種ファイルの読込

railsではSprocketsというアセットパイプラインを行うライブラリを
使用しています。
アセットパイプラインはJavaScriptやCSSを結合、圧縮して読込む
事でリクエスト量を減らす機能です。

このSprocketsの設定が必要になります。
プロジェクト配下の下記ファイルに緑の文字部分を追加して下さい。

[app/assets/javascripts/application.js]
 //= require turbolinks
 //= require_tree .
 //= require bootstrap

[app/assets/stylesheets/application.css]
 *= require bootstrap.min
 *= require_tree .
 *= require_self

こうする事でBootstrapがhtmlに対して読み込まれます。

■4.クラスの指定

勿論、読込んだだけでは意味が無いのでCSSのクラスを指定し
反映させます。

追加したのは下記の緑の部分です。

[index.html.erb]
 <h1>Listing tasks</h1>
 <table
class="table table-striped">
   <thead>
     <tr>
       <th>Title</th>
       <th>Priority</th>
       <th>Start</th>
       <th>End</th>
       <th>Location</th>
       <th>Person</th>
       <th colspan="3"></th>
     </tr>
   </thead>
   <tbody>
     <% @tasks.each do |task| %>
       <tr>
         <td><%= task.title %></td>
         <td><%= task.priority %></td>
         <td><%= task.start %></td>
         <td><%= task.end %></td>
         <td><%= task.location %></td>
         <td><%= task.person %></td>
         <td><%= task.tag %></td>
         <td><%= link_to 'Show', task %></td>
         <td><%= link_to 'Edit', edit_task_path(task),
:class => 'btn btn-primary' %></td>
         <td><%= link_to 'Destroy', task, method: :delete,
:class => 'btn btn-warning', data: { confirm: 'Are you sure?' } %></td>
       </tr>
     <% end %>
   </tbody>
 </table>
 <br>
 <%= link_to 'New Task', new_task_path,
:class => 'btn btn-primary' %>

修正はわずかですが、反映前と反映後を比較するとかなりイメージが
変わっているのが分かります。

[反映前の画面]



[反映後の画面]


BootstrapはCSSやJavascriptなので、Rails以外への適用もできます。
簡単に見栄えがよくなるので一度使ってみるのをオススメします。


前回に引き続きWebデザインの復習。

Webにおいて、デザインを行う為にはCSSを使用します。
CSSの対象を選択するのがCSSセレクタと呼ばれるものです。
多くの種類があり、覚えるのが大変ですが思い通りデザインする為には
是非、覚えるべきです。

今回は私がよく使うCSSセレクタを説明します。

まずは基本的なセレクタ。
ここら辺は絶対知っておくべき。

■1.型セレクタ

タグ名を指定してスタイルを変更

タグ名{ }
例)  html { font-family: serif;}

■2.全称セレクタ

全体のスタイルを変更

* { }
例) * {margin: 0;}

■3.クラスセレクタ

指定クラス名を持った要素のスタイルを変更

.クラス名 { }
例) .blue { color: blue;}

■4.IDセレクタ

指定IDを持った要素のスタイルを変更

#ID { }
例) #text1 { color: red; }


ここからは知ってたら、かなり便利な属性セレクタです。

■5.属性セレクタ(属性指定)

指定属性を持った要素のスタイルを変更

[属性名] { }
例) input[disabled] { color: black }

disabledとかreadonlyとかに使う。

■6.属性セレクタ(=)

指定属性、指定値を持った要素のスタイルを変更

[属性名=値] { }
例) input[type="text"] { color: white }


■7.属性セレクタ(~=)

指定属性が複数の値を持っている場合にそのうちの一つの値でも
同じ要素のスタイルを変更

[属性名~=値] { }
例) input[class~="w2"] { width: 240 }

主にクラス属性で使う。


■8.構造疑似クラス(nth-child)

子要素である指定した位置(順番)の要素のスタイルを変更

nth-child(位置) { }
例) input:nth-child(1) { background-color: yellow; }

10n-1といった指定やodd(奇数)、even(偶数)という指定もできる。
excelの表みたいのもこれで簡単に作れる。

■9.構造疑似クラス(last-child)

子要素の最終要素のスタイルを変更

last-child { }
例) div:last-child { background-color: blur; }

last-child(n)といった後ろからn番目という指定も可能。

■10.構造疑似クラス(nth-of-type)

同じ型を持つn番目の要素のスタイルを変更

nth-of-type(n) { }
例) p:nth-of-type(3) { backgroud-color: red; }

nth-childと似ているが、こちらは型を指定できる点や
子要素では無い点に注意。

セレクタは他にもありますが、自分がよく使うのはこんなとこです。


上記のセレクタと下記の結合子を組み合わせる事で
柔軟に要素を指定できます。


■a b

aやbは型、ID、クラスなど。
aの子孫のbといった意味になります。子の子なども含む。

■a > b

aの直接の子であるbという意味。

■a + b

aの直後のbという意味。

■a ~ b

aの後のb全部という意味。


あと、CSSを適用する上で優先順位が重要になります。

基本はincludeの順番ですが
style属性で直書き > IDセレクタ > クラスセレクタ > 型セレクタの
順でスタイルは優先となります。
さらにプロパティに !importantがついているのが最優先ですが
最後の手段としてあまり使わないようにしましょう。

最近、業務で画面作成をしているのでデザインについて復習する。

昔は画面デザインと言ったらTableタグを使ってましたが今では
Divタグ等をCSSでデザインするのがまわりでは主流になっています。

これはアクセシビリティ等の理由も勿論ありますが、業務システムでは
一番の理由は「デザインと構造」の分離だと思います。

デザインと構造をCSS, HTMLに分ける事で変更が簡単になります。
手で変更するのも、JS等で動的に変更する事も簡単になります。

CSSを使ったデザインは慣れれば簡単だけど、いくつかポイントがある。

■1.ブロック要素/インライン要素
htmlのタグにはブロック要素とインライン要素という種類があります。
ブロック要素は画面の横幅いっぱいに広がるもの。
インライン要素は自分の要素が入る範囲ギリギリになるもの。
pとかdivとかformとかのタグ。

■2.float
左や右に寄せるのに使います。後続の要素は回り込むように
表示されます。
これを使う事でブロック要素でも横並びにできます。

■3.clear
floatとセットで使う。
横並びでなく通常通り、下に並べたい場合にfloatの後、clearで解除する。

他にも色々ありますが、まずはこの辺から抑えると良いです。

具体例を説明していきます。

ブロック要素であるdivに対して背景色をつけて分かりやすくした例です。
ブロック要素が画面いっぱいに広がっている事が分かります。



[html]
 <html>
 <head>
   <style type="text/css">
     div{ background-color: lime; }
   </style>
 </head>
 <body>
   <div>
     <label for="text_1">Test1</label>
     <input id="text_1" type="text" />
   </div>
 </body>
 </html>

次にfloat: leftを使った例です。



それぞれのブロック要素が左寄せになると同時に幅が最少となっています。

[html]

 <html>
 <head>
   <style type="text/css">
   div{ float: left; background-color: lime;}
   </style>
 </head>
 <body>
   <div style="float: left;">
     <label for="text_1">Test1</label>
     <input id="text_1" type="text" />
   </div>
   <div style="float: left;">
     <label for="text_2">Test2</label>
     <input id="text_2" type="text"/>
   </div>
   <div style="float: left;">
     <label for="text_3">Test3</label>
     <input id="text_3" type="text" />
   </div>
 </body>
 </html>


最後にfloat: rightとclearを使った例です。



float:rightを使ったTest1, 2が右寄せになっていて、clearを指定した
Test3は回り込みが解除される為、次行に表示されます。
celarを指定しない場合、回り込む状態になる為、Test3がTest1,2と
同じ行に表示されます。

[html]

 <html>
 <head>
   <style type="text/css">
     div:nth-child(1){ float: right; background-color: lime; }
     div:nth-child(2){ float: right; background-color: lime; }
     div:nth-child(3){ clear: both; background-color: lime; }
   </style>
 </head>
 <body>
   <div>
     <label for="text_1">Test1</label>
     <input id="text_1" type="text" />
   </div>
   <div>
     <label for="text_2">Test2</label>
     <input id="text_2" type="text"/>
   </div>
   <div>
     <label for="text_3">Test3</label>
     <input id="text_3" type="text" />
   </div>
 </body>
 </html>


前回に引き続きアプリを作っていく訳ですが、せっかくなので
Heroku(ヘロク)というPaaS上にアップロードしていきます。

PaaSとはクラウド上のAPサーバです。
Herokuは無料で使え多くのツールもあります。
機能を拡張したければ有料で可能です。

まずはHerokuに登録します。



上記、登録画面で氏名、メールアドレス、会社名を入力して
確認メールを受け、確認メール内のURLからパスワードを設定します。

設定が終わったらログインします。



Ruby, PHP, Node.js, Python, Java, Clojure, Scalaが使えるようです。

今回はRubyなので「Ruby Get Started」を選択します。
するとチュートリアルが記述されているのでチュートリアルに従い
順に進めます。

Introductionは説明だけです。




次のSet upでは
ToolbeltというHerokuをコマンドラインで操作するユーティリティを
インストールします。

Gitも一緒にインストールされます。
コマンドラインで「heroku version」と入力してバージョンが表示されれば
正しくインストールできています。

ローカルのアプリケーションをheroku上で動くように

Gemfileを修正します。

[Gemfile] 変更前

 gem 'sqlite3'

[Gemfile] 変更後
 group :development do
   gem 'sqlite3'
 end
 group :production do
   gem 'pg'

   gem 'rails_12factor'
 end

これは常にsqlLiteを使う設定だったのをプロダクション(本番)
環境であるheroku上ではpostgreSQLを使うようにしています。

また、heroku上でrailsを使う為にrails_12factorというのを使うよう
設定してます。

ログや各種静的ファイルがheroku用に設定してくれるものです。

アップロードの為、Gitにローカルアプリケーションを追加します。

以下のように対象のフォルダで入力してください。

git init
git add .
git commit -m "コメント"

※適宜、.gitignoreファイルに除外したいファイルは登録して下さい

それぞれ以下の処理が行われます。
git init・・・カレントフォルダにGitリポジトリを作成
git add・・・指定フォルダをコミット対象にする
git commit・・・ローカルリポジトリにコミットする。

メールアドレスと名前を登録していない場合は
git commit時に「*** Please tell me who you are」と言われるので
git config --globalでメールアドレスと名前を登録して下さい。

herokuへアップロードする為に、まずログインします。
プロンプトからheroku loginコマンドを実行すればOKです。


登録時のメールアドレスとパスワードを入れて下さい。
ここでSSH鍵が無い場合は作成するか聞かれるらしいです。
(自分は聞かれなかった)


ではherokuのアプリを作ります。
「heroku create」とプロンプトで入力します。



すると上のように表示されます。
この中のhttp~が自分のアプリのURLになります。

次にGitのローカルリポジトリの内容をheroku上に
アップロードします。

プロンプトから
「git remote add heroku git@heroku.com:アプリ名.git」(初回のみ)
と「git push heroku master」を入力します。

もし、git push時に「Permission denied (publickey).」と表示された
場合は「heroku keys:add」と入力してSSH鍵を作って下さい。

heroku上でpostgresqlを使うにはアドオンを追加する必要があります。
「heroku addons:add heroku-postgresql」と入力してください。

また、config配下のdatabase.ymlもheroku用に修正する必要があります。

[database.yml]

 production:
   encoding: utf8
   adapter: postgresql
   port: 5432
   username: heroku postgresのユーザ名
   password: 
heroku postgresのパスワード
   host: 
heroku postgresのホスト名
   database: heroku postgresのデータベース名


heroku上でマイグレートするには
「heroku run rake db:migrate」と入力します。

herokuへアップロードが終われば、このように実行できます。
URLを直接指定するか、プロンプトから「heroku open」と
すればよいです。


次回以降は、このタスクスケジューラアプリを修正していきます。

前回まではRailsにおけるModel, View, Controllerを修正すると
ともに役割の説明をしていきました。

今回からはRailsで簡単なタスクスケジューラを作っていきます。

まずは簡単に仕様を考えます。

登録したタスクが一覧で表示され、いくつかの条件で
フィルタリングやソートできるものにします。

システム名は「TaskScheduler」に。

早速プロンプトから「rails new TaskScheduler」

なぜか、以下のエラーが表示されたので

Gem::RemoteFetcher::FetchError: SSL_connect returned=1 errno=0 state=SSLv3 read
server certificate B: certificate verify failed (https://rubygems.org/gems/rake-
10.4.2.gem)
An error occurred while installing rake (10.4.2), and Bundler cannot continue.
Make sure that `gem install rake -v '10.4.2'` succeeds before bundling.

ここ見て直した。
http://qiita.com/shimoju/items/394818b4989b94680aaf

証明書が更新された事が原因らしい。

アプリケーションを作った後はscaffoldを使ってコントローラやモデルを
作ります。

scaffoldの前に必要なテーブルを設計します。
タスク内容を登録するTaskテーブルを作成します。
その項目として以下の7つ。

Title:題名
Priority:重要度
Start:開始日
End:終了日
Location:場所
Person:関係者や当事者
Tag:その他
CreateTime:登録時間

作成コマンドは
「rails g scaffold scaffold task title:string priority:integer start:datetime
end:datetime location:string person:string tag:string」

続いてDBの作成
「rake db:migrate」

ここまでで作られたものが以下。

登録画面



一覧画面



今後はレイアウト修正や機能追加していきます。

今までModel, Viewと変更をしてきましたが残るControllerの修正を今回行います。

Controllerとはユーザからリクエストを受けてModel, Viewと
連携して結果をユーザに返すものです。
名前通り、Model, ViewをControlします。

前回までの状態で動かすと、正常に登録されません。



上記のように登録しても



このように表示されません。
rails consoleを使ってUserモデル経由で
Userテーブルの内容を確認してみると



画面から登録したはずの値が全てnil になってます。



リクエストの内容を開発ツールで見てみると
しっかりとuser[no], user[first_name], user[last_name]というキーで
値が送られていました。

上記のようにControllerに対して正しくリクエストが送られて
いてもControllerを修正しなければDBに対して正しく
登録がされません。

問題となる箇所はControllerの以下の記述です。

[users_controller.rb]

 def user_params
   params.require(:user).permit(:name, :mail)
 end


これはViewから受け取ったハッシュのうち許可するパラメータを
指定するもので、Strong Parametersと呼ばれる機能です。
つまり上記だとviewから受け取ったuserハッシュのうち
nameとmailだけを許可している訳です。
画面外から呼び出された場合の為に主に使います。

こちらを前回までの修正に合わせたのが以下。

[users_controller.rb]

 def user_params
   params.require(:user).permit(:no, :first_name, :last_name)
 end


修正した所、DB登録&画面表示されるようになりました。

前回、Modelを修正した事でView表示時にエラーが発生していましたので
今回はViewを修正していきます。



erbの16行目
<%= f.text_field :name %>
の箇所でエラーが発生している事が分かります。

これはフォームヘルパというヘルパの一種であり
このtext_filedヘルパはテキストボックスのHTMLを作成します。

ここではUserモデルのname属性の値を初期値としようとして
name属性が無くなっているのでエラーとなっていた訳です。



現在のモデルに合わせてviewを修正します。



修正した所、正常に表示できるようになりました。



他のerbも同様に修正していく必要があります。
例えばshow.html.erbですが

モデルをしようしていた箇所を以下のように修正しました。

[show.html.erb]

<p>
  <strong>No:</strong>
  <%= @user.no %>
</p>

<p>
  <strong>FirstName:</strong>
  <%= @user.first_name %>
</p>

<p>
  <strong>LastName:</strong>
  <%= @user.last_name %>
</p>


上記の@user.~部分はインスタンス変数のuserでUserモデルを
インスタンス化したものです。
Userモデルを変更したので使用する属性を合わせて修正しました。

これで実行時にエラー出力されないようになりましたが
まだ正常ではありません。
次回はコントローラを修正し正常に動作するようにします。

前回作ったアプリケーションを修正していきます。

まずはModelのフィールドを変更しようと思います。
フィールドを追加したり削除したりもできますが、今回は一旦削除して
再作成します。

モデルを削除するには
rails destroy model モデル名
と指定します。

モデルを作成するには
rails generate model モデル名 フィールド名:型・・・
と指定します。
※genarete を g と省略する事も可能

作成されるテーブルはモデル名にsをつけたものとなります。
今回はモデル名をuserとしたのでテーブル名はusersです。

モデルは以下の位置に作成されています。
ルート\app\models\モデル名.rb

[user.rb]
 class User < ActiveRecord::Base
 end


上記のようにActiveRecord::Baseを継承したクラスが作成されてます。
こちらは拡張していなければ削除前と同内容です。
このようにActiveRecordを継承する事でテーブルの項目を
クラスのメンバとして持つことができます。

では、テーブルの項目を見ます。
テーブルは rake db:migrate コマンドにより作成されますが
テーブルのもととなる定義ファイルは以下の位置にあります。

ルート\db\schema.rb

[schema.rb]
 ActiveRecord::Schema.define(version: 20141117140714) do

   create_table "users", force: true do |t|
     t.string   "no"
     t.string   "first_name"
     t.string   "last_name"
     t.datetime "created_at"
     t.datetime "updated_at"
   end


 end

usersテーブルが作り直されている事が分かります。
項目としてはno, first_name, last_name, created_at, updated_atが
用意されています。

上記のように rails destroy model ~, rails generate model ~と
モデルだけ作り直した場合は当然、ビュー表示時にエラーになります。
ビューとの不整合が原因です。


次回はエラー表示されないように、ビューを今回の修正に合わせて
変更します。
前回 rails new コマンドで作ったアプリケーションにScaffold
を使って動作するようにしていきます。


1.Scaffoldでアプリケーションを作成する場合、以下のように指定します。

rails generate scaffold モデル名


今回は
「rails generate scaffold user name mail_address」 としました。
これはname, mail_addressというフィールドを持ったuserというモデルを
作成する事を表してます。

また、このコマンドをアプリケーションのルートで実行する事で

以下の部品(ファイル)が作成されます。

・コントローラ
⇒リクエストを受けて、モデルやビューと連携する

・ビュー
⇒画面。rubyではerbが一般的。

・モデル
⇒データベースを操作する

・マイグレーション
⇒DBを設定する

・ルーティング
⇒リクエストとコントローラのアクションを紐付ける

・アセットパイプライン
⇒JavaScriptやCSS, 画像ファイルを圧縮したり連結することで
 効率的にアクセスできるようにしたもの

・ヘルパー
⇒よく使う処理を簡単に記述できるようにしたもの

・テスト
⇒テスト用


2.次にDBのマイグレートを行います。

rake db:migrate



マイグレートを行う事でテーブルの作成や初期データの登録がされます。


3.次にWebサーバを起動します。

rails server

起動したらブラウザからアクセスして作成したアプリケーションを試します。

ブラウザから「http://localhost:3000/users」を指定して
画面を表示します。


初期画面です。
まだデータが何もないのでデータ登録用のリンクのみです。



New Userをクリックして登録画面を表示した所です。
適当にデータ登録してみる。



項目に値を入れたらCreate Userボタンを押す。



登録結果画面が表示されました。
この時点で登録したデータはデータベースに格納されます。

Backを押すと、一覧画面に戻ります。



最初は何もデータが表示されてませんでしたが
1件登録したので登録データが表示されています。

この一覧から
Showを押せば詳細画面が



Editを押せば更新画面が



Destroyを押せば削除確認画面が表示されます。




このようにscaffoldを使うことで簡単なアプリケーションが作成できます。
scaffoldで作成されたファイルを変更していく事で目的のアプリケーションに
近づけていくのがscaffoldを利用した開発です。