"return"というコマンドの理解を通してcodingについて考えてみる


def sayHi(name = "Steve")
s = "hello!" + name
# メソッドは返り値を持たせることも出来る。ここではsが返り値
return s # returnは省略可能
end
ここではdef sayの部分で何も名前を指定しない場合はSteveとなるように設定がなされている。
次の行でsを打つとhello入力した名前(何も入力がない場合はSteve)となるように命令をしてあげる。

# 返り値を持つのでメソッドの結果を代入することが可能
greet = sayHi()
puts greet # hello! Steve

# このメソッドで定義された変数は外からアクセスできない!!
# defとendの間でしかsという変数は定義されていないから
puts s # とやるとエラーを吐く

これはつまりどういうことなのか。要するに各ファイルというのはパソコンに流した時にどう出力されるのかをこちら側で指定する必要があるわけである。もっと簡単に説明するために以下の例を見てみる。Controller.rbというファイルに以下のコーディングがなされていたとする。

def test
p'hello'
end #ここまでをpart1と呼ぶことにする

p world

def world
return 'world'
end # part1の終わりからここまでをpart2と呼ぶことにする

def hoge
w = 'yeah'
h = 'hey'
z = 'god...'
return h # return hがないと'god...'出力されてしまう
end
p hoge # part2の終わりからここまでをpart3と呼ぶことにする

このままパソコンに流すとpart1は何も出力されない。testというアクションがどこにも定義されていないからである。これはまるでパソコンに向かって「testというアクションがあるからhelloとプリントしてね」と言っていることと同じである。現実の世界ではこいつが何をしようとしているか大体の検討がつくがプログラミングの世界では「testというものがこういうものでこのコマンドを入力するとこのように出力されるという詳細な流れを書かなければならないのである。
part2はこのファイルで一番最初に出力される部分である。ファイルをコンピュータに流すとコンピュータは上からコードの出力を行うのだが、part1が出力されないため一番最初に出力されるのはpar2の部分。つまりworldである。これはあえてp worldを最初に書いたのだが仮にコンピュータが定義なしのworldを確認したとしてもその下にちゃんとworldに戻ってくるように定義されているのである。(これを返り値と呼ぶ)
part3は結果としてheyが出力されるようになっている。しかしもしreturnというコマンドを消したとしたら出力される値は'god...'である。何故かと言うとコーディングは上から下にかけて順番に読み込んでいく特性があり、正確な定義やコマンドが無い限りはその方法によって情報が出力されるからである。

railsで作った読書管理アプリをグレードアップさせてみる

前回作った簡易的な読書管理アプリをグレードアップさせてみる。結局もう一回作りなおさないといけないは目になったのだが、現時点で付属されている機能は読んだ本のタイトルが記録できる、読んだ本を一覧で見られる、読んだ本の記録を削除できる、読んだ本の名前の変更ができるだけである。

ここに以下の機能を付属させるところまでやってみる。

  • 読んだ本にコメントをつけられる
  • 読んだ本にスコアをつけられる
  • 関連書籍を設定できる
  • 関連書籍へのサイト内リンクがある
  • 本のタイトルやコメントを空欄で保存できないようにする

以上が余裕だったら

  • 読んだ日時を記録できるようにする
  • 本の画像を保存できるようにして、本の画像も表示されるようにする
  • 友達に本をオススメする機能を作る
  • 読んだ本にタグ付けして、タグごとに本の一覧を見られるようにする
  • ユーザー登録機能をつけて、ユーザーごとに別々に管理できるようにする

Scaffoldで作ったdabaseに新たなフィールド(カラム)を追加してみる

実際にscaffoldで作ったんだけど新たにフィールドを作成する場合は一度destroyコマンドを使って消してから再度フィールドを全て含めた上でもう一回作りなおすのがいいが、ある程度自分で手を加えてしまったので消すのは面倒臭いという場合は、modelのフィールドを追加するために新しくg modelの中のmigration fileを追加する。そのファイルの中に行う必要のあるアクションを記入する。migration file建築内容の指示書。db:migrateを行うことによって命令することができる、と考えれば良い。


# マイグレーションファイル作成コマンド
$ rails generate migration クラス名
クラス名は何でもいいが「アクション+テーブル名」が慣例。これで/db/migrate/タイムスタンプ_クラス名.rbというファイルが作られる。 しかしこのままだと実際のDBには反映されないので、db:migrateコマンドを実行する。念のため他のアクションコマンドも記載しておく。後々使えそうだし。

# 実行
$ rake db:migrate
# ロールバック
$ rake db:rollback # ロールバックを使用することによって一つ前の状態に戻ることが出来る。
# 確認
$ rake db:migrate:status

# すでに実在しているフィールドを変更する
$ rails g migration ChangeColumnToUser

# 変更内容
def up
change_column :users, :uuid, :string, null: false, default: 0
end

# 変更前の状態
def down
change_column :users, :uuid, :string, null: true, default: 0
end
end


フィールドを追加/削除する
$ rails g migration AddColumnToUser フィールド名:フィールドの種類

/db/schema.rbに全ての指示が記載されているのでそこに変更が記載されていれば成功したという意味。
class AddColumnToUser < ActiveRecord::Migration
def change

# 追加
add_column :users, :piyo, :string

# 削除
remove_column :users, :piyo, :string

# 追加する場所を指定する場合
add_column :users, :piyo, :string, :after => :uuid
end
end

成功するとこんなかんじではきだしてくれる。

参照:
rails generate migrationコマンドまとめ
Railsのmigrationの基本とレシピ集

ファイルのネーミングについて

色々と作業をしていて個人的に厄介だと思っていることがファイルのネーミングである。前の記事で紹介したように基本的にファイルの命名は「アクションとテーブル名の組み合わせ」である。理由はそのファイルを見ただけで何のためにそのファイルが存在するのかが一目でわかるからである。あとは規則的に決めておくことでそのファイルを起動する必要になった時にトラブルが起こりにくい。ネーミングにおいてのtipsは以下のとおり。
生DBは複数形、小文字(今回のプロジェクトではbooksとなっている。複数の情報を入れておくという意味で)
Modelないのファイルに関しては基本的に大文字単数形で表現したほうがいい。(booksという概念を扱うから)
Migration fileはg migration AddColumnToBook。ちなみにAddColumnというのはアクション名でBookがクラス名にあたる。もっと簡単に言うと、クラス(オブジェクトを入れる箱)が基本的に単数形でオブジェクトは複数あるから複数形になると考えると分かりやすいかもしれない。

rake routesというコマンドが意外と便利

「rake routes」というコマンドを使うと意外と便利。「ファイルが増えていくとさすがにファイル名だけではどれがどことつながってるのかわからない!」とか俺みたいな雑魚がほざいてるやつにとってはこういうコマンドがめっちゃ便利だったりする。これをterminal上で打ってみると、


User-no-MacBook-Air:books user$ rake routes
Prefix Verb URI Pattern Controller#Action
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
root GET / welcome#index
例えば「ブックスのページの元ページってどこにあるんだろう」みたいなときとか「これってbooksのindexでいいの?」なんていう時にこれで一度ファイルのルーティングを確認しておくと仕事が捗ったりする。俺みたいなやつには便利だよっていう話。