小学生でもわかるRuby on Rails入門のメモ

* [小学生でもわかるRuby on Rails入門 | OpenBook](http://openbook4.me/projects/92/)の学習メモ

## vim-railsが便利

```bash:
cd ~/.vim
git clone https://github.com/tpope/vim-rails
echo "set runtimepath+=${HOME}/.vim/vim-rails/" >> ~/.vimrc
```

* `:R`でview<-->contollerを切り替えられる。
* `:Vview`

## パッケージの準備

```bash:
apt-get install -y sqlite3 libsqlite3-dev zlib1g-dev
gem install rails
gem install rake
```

```bash:プロジェクトの作成
rails new twitter
cd twitter
```

## users/show作成

```ruby:viewとcontroller作成
rails g controller users \
 index show
```

```bash:3000ポート
rails s
```

* http://localhost:3000/users/show

## get値の取得

```rb:config/routes.rb
get 'users/index'
get 'users/show'
get 'users/show/:username' => "users#show"
```

* users/show/:username にアクセスしたら UsersControllerのshowを明示的に利用するという意味。
* get値の参照 => `params[:username]`


## DB

* データベース : ノート
* スキーマ　　 : 情報を入力するための共通の枠

```bash:DBの作成
rake db:create
```

* db/development.sqlite3 が生成される。

## migrate

```bash:
rails g model user \
  name:string \
  username:string \
  location:string \
  about:text
```

```bash:sqlite3に反映
rake db:migrate
```

## 初期データ

```bash:db/seeds.rb
@user = User.new
@user.name = 'Ryo Suzuki'
@user.username = 'ryooopan'
@user.location = 'Kanagawa, Japan'
@user.about = 'Hello, I am Ryo. I am from database!'
@user.save

@user = User.new
@user.name = 'Shohei Aoki'
@user.username = 'moyahima'
@user.location = 'Tottori, Japan'
@user.about = 'Nice to meet you. I am from database!'
@user.save
```

```bash:初期データ投入
rake db:seed
```

```bash:検索
@user = User.find_by(:username => params[:username])
```

```erb:app/views/users/show.html.erb
<h1><%= @user[:name] %></h1>
<p><%= @user[:username] %></p>
<ul>
  <li>Location : <%= @user[:location] %></li>
  <li>About    : <%= @user[:about] %></li>
</ul>
```

----

# twitterっぽいやつ

## rails g

```bash:viewとcontoller作成
rails g controller tweets \
 index show new
```

```bash:model作成
rails g model tweet \
 title:string \
 content:text
```

```
rake db:migrate
```

* http://0.0.0.0:3000/tweets/new

```rb:app/views/tweets/index.html.erb
<a href="/tweets/new">投稿</a>

<% @tweets.each do |tweet| %>
  <h1><%= tweet.title %></h1>
  <p><%= tweet.content %></p>
<% end %>
```

```erb:app/views/tweets/new.html.erb
<%= form_for Tweet.new do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>
  <%= f.label :content %>
  <%= f.text_area :content %>
  <%= f.submit %>
<% end %>
```

```rb:config/routes.rb
get 'tweets/index'
get 'tweets/show'
get 'tweets/new'
post 'tweets' => "tweets#create"
```

## データの保存

```bash:app/controllers/tweets_controller.rb
  def create
    @tweet = Tweet.new
    @tweet.title = params[:tweet][:title]
    @tweet.content = params[:tweet][:content]
    @tweet.save
    redirect_to '/tweets/index'
  end
```

* postしたら /tweets/index に飛ぶ

```rb:
class TweetsController < ApplicationController
  def index
    @tweets = Tweet.all
  end
...
```

----

# 別の書き方

* [補足 (小学生でもわかるRuby on Rails入門) | OpenBook](http://openbook4.me/projects/92/sections/503)

## config/routes.rb

```rb:
resources :tweets
resources :users
```

## 保存時のエラー対応

* [ruby on rails - ActiveModel::ForbiddenAttributesError when creating new user - Stack Overflow](http://stackoverflow.com/questions/17335329/activemodelforbiddenattributeserror-when-creating-new-user)

```diff:app/controllers/application_controller.rb
  class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception
  
+   before_filter do
+     resource = controller_name.singularize.to_sym
+     method = "#{resource}_params"
+     params[resource] &&= send(method) if respond_to?(method, true)
+   end
  end
```

```diff:app/controllers/tweets_controller.rb
  class TweetsController < ApplicationController

    def create
-     @tweet = Tweet.new
-     @tweet.title = params[:tweet][:title]
-     @tweet.content = params[:tweet][:content]
-     @tweet.save
-     params.permit!
+     @tweet = Tweet.create(params[:tweet])
      redirect_to '/tweets'
    end

+   private
+   def tweet_params
+     params.require(:tweet).permit(:title,:content)
+   end

  end
```