ブログのソースコードに色つけるやつを変えた

WordPressのクレヨンとかいうやつから、ここに書いてあるHighlight.jsのやつに変えた。ついでにマークダウンも追加した。クレヨンはpreで囲まれた中身を自動で変換するが、highlight.jsはpre > codeで囲まれた中身を変換するので、シンプルな移管ができなそうな状況になった。ちょっと調べたけど、対応するタグをpre >
code
以外にも追加するようなことはできないっぽいので、データベースのprepre > codeに変換することにした。一応バックアップとった。

いいプラグインを発見した。正規表現も使えるので、これを使ったら一瞬で終わった。
Search Regexプラグインの使い方

Rails – 色々やってみる

$ rails new rails1
$ cd rails1
$ rails db:migrate

プロジェクト作っていきなりdb:migrateしたら、developement.sqlite3と、schema.rbが作成された。中身はからなはず。DataGrip使って見てみる。空だ。
とりあえず1つscaffoldする。

$ rails g scaffold user name:string email:string
      invoke  active_record
      create    db/migrate/20170411151003_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      create      app/views/users/_user.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.coffee
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

大量のものを作成している。
この状態で、rails sをすると下記エラーがでる。

Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development

マイグレーションをDBに反映してないことが分かるようです。
マイグレーションファイルを見てみます。

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

ではSQLiteを見てみます。DataGrip便利だな。usersテーブルができていて、created_at、updated_atもあります。idというプライマリーキーもあります。
scaffoldするとjsonにも対応している。

とりあえずViewにBootstrapを適用してみる。その前に、cssとかの読み込み状態を確認してみる。

<link rel="stylesheet" media="all" href="/assets/scaffolds.self-50415e02e26bd1d252d84df1b2baeea859ec7e1c4f26c45a801029454454bc62.css?body=1" data-turbolinks-track="reload" />
<link rel="stylesheet" media="all" href="/assets/users.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" />
<link rel="stylesheet" media="all" href="/assets/application.self-af04b226fd7202dfc532ce7aedb95a0128277937e90d3b3a3d35e1cce9e16886.css?body=1" data-turbolinks-track="reload" />
    <script src="/assets/jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/jquery_ujs.self-784a997f6726036b1993eb2217c9cb558e1cbb801c6da88105588c56f13b466a.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/turbolinks.self-c5acd7a204f5f25ce7a1d8a0e4d92e28d34c9e2df2c7371cd7af88e147e4ad82.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/action_cable.self-5454023407ffec0d29137c7110917e1e745525ae9afbc05f52104c4cd6597429.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/cable.self-6e0514260c1aa76eaf252412ce74e63f68819fd19bf740595f592c5ba4c36537.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/users.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/application.self-b89234cf2659d7fedea75bca0b8d231ad7dfc2f3f57fcbaf5f44ed9dc384137b.js?body=1" data-turbolinks-track="reload"></script>

なんか激しい感じだ。cakephpと違ってAssetまで融合させようとしている感じがひしひしと伝わってくる。
app/assets/javascrptsとapp/assets/styleshetsの中にあるものが全部読み込まれている。

<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

この設定を変えると変わるはず。Jsはjquery,jquery-uiとかも勝手にインストールされている。外す方法確認しないと。

下記のようにやると、assetが結合・圧縮されるらしい。処理内容は設定によるだろうけど。

$ rails assets:precompile RAILS_ENV=production

app/assets/javascripts/application.jsと、app/assets/stylesheets/application.cssには、下記のような記述がありここを変更すると読み込む内容を変更できるらしい。

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

assetが便利だけど複雑だな。rails sをやり直さないとエラーのままになることあるな。

$ rails assets:precompile RAILS_ENV=production

をやったら、確かにpublic/assetsに圧縮されたものが格納された。
js/css共に1つのファイルが出力された。あとはgzファイルもある。このコンパイルをしておけば、本場環境ではこれらを読み込むようになるはず。

Railsのコード短いなー。scaffoldだとバリデーションないので、モデルのバリデーション入れてみる。

class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
            format: { with: VALID_EMAIL_REGEX },
            uniqueness: { case_sensitive: false }
end

入力画面で空状態で登録押すとエラーでる。cakephpみたいにformにまでvalidationが反映されるわけではないのかな。
英語のエラーだから日本語にしてみる。Djangoみたいに、設定ファイルで日本語ってやると日本語になるわけではないらしい。
やり方ここに書いてあった。

ja.ymlをconfig/locales/に追加
config/application.rbにconfig.i18n.default_locale = :jaを追加
サーバーを再起動
さらにモデルの属性名(nameなど)を日本語化する場合は、ja.ymlに次のように記載して下さい。

# config/locales/ja.yml
ja:
attributes:
name: 名前

3 error prohibited this user from being saved:というバリデーションエラーのメッセージは英語のままだな。

new.html.erbがすごい。3行しかない。でもrenderだからパーシャルを読み込んでるわけで、全自動でフォームが作られてるわけではない。

<h1>New User</h1>

<%= render 'form', user: @user %>

<%= link_to 'Back', users_path %>

パーシャルは、下記のように書く。これは_form.html.erbを読み込む。アンダーバーがパーシャルのしるしらしい。

<%= render 'form'%>

パーシャルの内容は下記。

<%= form_for(user) do |f| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>

  <div class="field">
    <%= f.label :email %>
    <%= f.text_field :email %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

エラーメッセージがベタ打ちだから英語のままだったんだな。

エラーメッセージの表示方法はアプリケーションごとに異なるため、Railsではこれらのメッセージを直接生成するビューヘルパーは含まれていません。 しかし、Railsでは一般的なバリデーションメソッドが多数提供されているので、カスタムのメソッドを作成するのは比較的簡単です。また、scaffoldを使用して生成を行なうと、そのモデルのエラーメッセージをすべて表示するERBがRailsによって一部の_form.html.erbファイルに追加されます

bootstrapに対応して、エラーを日本語にしてみた。

<div class="row">
<%= form_for(user) do |f| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= user.errors.count %>件のエラーが発生しました</h2>
      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <div class="col-md-6">
    <%= form_for(@user, url: users_path) do |f| %>
        <div class="form-group">
          <%= f.label :name %>
          <%= f.text_field :name, class: 'form-control' %>
        </div>
        <div class="form-group">
          <%= f.label :email %>
          <%= f.email_field :email, class: 'form-control' %>
        </div>
        <%= f.submit "submit", class: "btn btn-primary" %>
    <% end %>
  </div>
<% end %>
</div>

エラー発生フィールドはエラークラスのdivで囲われるから、それにスタイルつければ、エラーここだよ、というのが示せる。

次は、モデル(アクティブレコードと呼ぶらしい)のクエリ系のやつ覚えて、セッション、キャッシュとか確認して、認証のやり方確認して、セキュリティに関して確認したら大体何でもできそう。

Rails – cannot load such file — bcrypt_extというエラー

cannot load such file — bcrypt_extというエラーがでた。

環境

Windows10
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]
$ rails -v
Rails 5.0.2

gemfileに下記を追加したらいいとここに書いてあった。

gem 'bcrypt-ruby', '3.1.1.rc1', :require => 'bcrypt'

だめだった。

ここに書いてあった。

C:\> gem install --no-ri --no-rdoc bcrypt
C:\> cd (path to gems root)\bcrypt-3.1.7-x86-mingw32\ext\mri
C:\(path to gems root)\bcrypt-3.1.7-x86-mingw32\ext\mri> ruby extconf.rb
C:\(path to gems root)\bcrypt-3.1.7-x86-mingw32\ext\mri> make
C:\(path to gems root)\bcrypt-3.1.7-x86-mingw32\ext\mri> make install

path to gems rootは、下記で調べられる。

$ gem environment
  - GEM PATHS:
     - D:/Ruby23-x64/lib/ruby/gems/2.3.0
     - C:/Users/hoge/.gem/ruby/2.3.0
$ cd /D/Ruby23-x64/lib/ruby/gems/2.3.0/gems
$ ls bcrypt-
bcrypt-3.1.11-x64-mingw32/ bcrypt-ruby-3.1.1.rc1/
$ cd bcrypt-3.1.11-x64-mingw32/ext/mri/
$ ruby extconf.rb
$ make
bash: make: command not found

makeをwindows10にインストールした

$ make

make: *** `bcrypt_ext.o’ に必要なターゲット `/D/Ruby23-x64/include/ruby-2.3.0/ruby.h’ を make するルールがありません. 中止.

なんだこれは。。

ここに下記が書いてあった。
I solve it with uninstall all bcrypt gem versions with gem uninstall bcrypt and select option 3 (if exist) and uninstall all bcrypt-ruby gem versions with gem uninstall bcrypt-ruby and select option 3 (if exist) then install bcrypt using gem install bcrypt –platform=ruby then add this line gem ‘bcrypt’, platforms: :ruby to Gemfile, that is it :D.

$ gem uninstall bcrypt
$ gem install bcrypt --platform=ruby
$ vim Gemfile
gem 'bcrypt', platforms: :ruby
$ rm Gemfile.lock
$ bundle

ダメだ。なんだこれは。。。

やっぱmakeを成功させてみる。

ここに書いてあった。

make: *** ‘ossl_pkey_dh.o’ に必要なターゲット ‘/include/ruby.h’ を make するルールがありません. 中止.

Makefileにtop_srcdirの定義が記述されていない。
top_dir行の下に追加する。
top_srcdir = /home/wheezy/src/ruby-2.2.2

$ gedit Makefile
$ make clean
$ make

無理わからん(T_T)

WindowsのRubyは色々大変らしい。こんなこと頻繁にあったらたまったもんじゃないっす。VagrantかDocker使おう。

Rails – Gemfile

Gemfileは使いたいgem書くファイル。bundle installするとインストールされて、Gemfile.lockが作られる。Gemfile.lockがある場合、bundle installするとGemfile.lockの内容が使われる。Gemfile.lockの内容を変えたいときは、Gemfile.lockを消すか、変えたいgemに対して、bundle updateすればいい。

Rails5のAPIモードでAPIをつくってみる(2)

Rails5のAPIモードでAPIをつくってみる(1)のつづき

検索機能つけてみる。

アクションを作る。

# GET /items/search
def search
  @items = Item.search(item_params)
  render json: @items
end

下記の詳細は、ここに書いてあった。

# Only allow a trusted parameter "white list" through.
  def item_params
    params.require(:item).permit(:name, :price)
  end

ルーティング設定する。ルーティングの説明は、ここに超詳しく書いてある。便利だなあ。cakephpより分かりやすい。コントローラのフォルダわけとかもcakephpよりやりやすいと思った。あと、パス作成も簡単でいい。

Rails.application.routes.draw do
  get '/items/search', to: 'items#search'
  resources :items
end

モデルにsearch関数を書く。
modelクラスの中でのselfの使い方
Active Record クエリインターフェイス

def self.search(data)
  name = data[:name].nil? ? '' : data[:name]
  items = self.where('name like ?', '%' + name + '%')
  items = items.where('price = ?', data[:price]) if data[:price].present?
  return items
end

これでとりあえずできた。sqlの見方調べよう。development.logに出力されてた。

SELECT "items".* FROM "items" WHERE (name like '%app%') AND (price = '500')

1回のセレクト文になってるから大丈夫っぽい。

Rubyのempty, false, nilなど

empty, false, nilとrailsにはblankもあるらしいけど、これしっかり覚える。

nil? empty? blank? present? の使い分け

nil? すべてのオブジェクトに定義されている。nilのときのみtrueを返す。
empty? 文字列の長さが0のとき、または配列が空のときにTrueを返す。もちろん数値には定義されていない。
blank? railsの拡張。nil, “”, ” “, [], {} のいずれかでTrueを返す。
present?は、!blank?と同じ意味

結果

・0 false nilは別物
・nil?は、nilのときtrue。
(未定義の変数に使うとエラーになる。存在する配列の中の、存在しない要素だとエラーにならず、trueを返す)
・empty?は、文字列、配列に使えて、空文字列か配列が空のときtrue
・blank?は、nil, false, 空文字列, スペースだけの文字列, 配列が空のときtrue
 (未定義の変数に使うとエラーになる。存在する配列の中の、存在しない要素だとエラーにならず、trueを返す)
・present?は、!blank?
PHPよりわかり易いと思った。
・変数が定義済みかを確認するには、defined?を使える。

irbでやってみる。

a = 1
a.nil?
false
a.empty?
ERROR
a.blank?
ERROR
a.present?
ERROR

b = ''
b.nil?
false
b.empty?
true
b.blank?
ERROR
b.present?
ERROR

c = false
c.nil?
false
c.empty?
ERROR

d = 0
d.nil?
false
d.empty?
ERROR

z.nil?
ERROR

定義してない変数にnil使ってもエラー。falseでも0でも定義さえしてたら、nilじゃない。

c == 0
false

falseは0でもnilでもない。

f = []
f.length
0
f.empty?
true
f.nil?
false

emptyは文字列、配列に使える。数値には使えない。

rails consoleでやってみる。

$ rails c
a = 1
a.empty?
ERROR
a.blank?
false
a.present?
true

b = 0
b.empty?
ERROR
b.blank?
false
b.present?
true

c = ''
c.empty?
true
c.blank?
true
c.present?
false

d = false
d.empty?
ERROR
d.blank?
true
d.present?
false

falseの場合もblank?はtrueを返す。

e = {}
e.empty?
true
e.blank?
true
e.present?
false

f(未定義)
ERROR
f.empty?
ERROR
f.blank?
ERROR
f.present?
ERROR

あら未定義だとblankもpresentもエラーになる。
railsのコントローラ上で試してみてもエラーになった。
定義済みじゃないとエラーになるのか。色々PHPと違う。

a = false
logger.debug 'a is blank' if a.blank?
# logger.debug a if b.blank?
c = {'a': 12, 'b':13}
logger.debug 'c[:a] is present' if c[:a].present?
logger.debug 'c[:c] is blank' if c[:c].blank?
d = '    '
e = '   '
logger.debug 'd is blank' if d.blank?
logger.debug 'e is blank' if e.blank?
logger.debug 'c[:c] is nil' if c[:c].nil?

上記をコントローラでやると、development.logに下記が表示される。

a is blank
c[:a] is present
c[:c] is blank
d is blank
e is blank
c[:c] is nil

配列の要素に対しては、blankを使ってもエラーにならないらしい。

また、rails consoleでやってみる。

c = {}
c['a'].blank?
true
c['a'].empty?
ERROR
c[:a].nil?
true

あとは一応クラスつくって試してみる。

class Hoge
  attr_accessor :name
end
a = Hoge.new
a.name
nil
a.name.nil?
true
a.name.empty?
ERROR
Hoge.nil?
false
Hoge.blank?
false
Hoge.present?
true
a.nil?
false
a.blank?
false
a.present?
true

変数が存在するか確認するには、definedが使えるらしい。

rails consoleで試してみる

a = false
b = ''
c = []
d = new Hoge

defined? a
=> "local-variable"
defined? b
=> "local-variable"
defined? c
=> "local-variable"
defined? d
=> "local-variable"
defined? c[:a]
=> "method"
defined? d.name
=> "method"
defined? d.hoge
=> nil
defined? z
=> nil

未定義の変数に使ったらnilが返ってくる。存在する配列の存在しない要素に使うと、methodって返ってくる。存在するオブジェクトの値がnilのメンバ変数に使うと、methodって返ってくる。

Railsのデバッグ方法

ログ出力

logger.debug "出力したいデバッグ情報"

オブジェクトをわかり易く表示

@test.inspect
p @test

RubyMineのデバッグ機能を使う
RubyMineでPowを使いながらDebugする方法

byebugというgemを使う
byebugでやるのはめんどうだからRubyMineのがいいや。

RubyMineでデバッグしてみる

Run -> Debug… -> Debug Development: hogeを実行すると、デバッグ用のサーバが立ち上がる。localhost:3000にアクセスすると、ブレークポイントついてるところでとまって情報が表示される。便利。

APIの場合どうなるか?
Debug Development: hogeを実行し、デバッグ用サーバを立ち上げておき、ブレークポイントをつけて、postmanでアクセスしたら、ちゃんと止まった。うれしいっす。すごい楽だな。

Powというのは便利そうだから今度しらべよう。

Rails5のAPIモードでAPIをつくってみる(1)

プロジェクト作成

$ rails new api1 --api

rails server立ち上げる

$ rails server

おーAPIモードになってる。
とりあえず、商品名と金額を登録・取得できる簡単なAPIをつくってみます。

商品テーブルのscaffoldとtableをつくる

$ rails generate scaffold Item name:string price:int
      invoke  active_record
      create    db/migrate/20170325093816_create_items.rb
      create    app/models/item.rb
      invoke    test_unit
      create      test/models/item_test.rb
      create      test/fixtures/items.yml
      invoke  resource_route
       route    resources :items
      invoke  scaffold_controller
      create    app/controllers/items_controller.rb
      invoke    test_unit
      create      test/controllers/items_controller_test.rb
$ rails db:migrate

エラーになった。intじゃだめっぽい。integerらしい。

$ rails destroy scaffold Item
      invoke  active_record
      remove    db/migrate/20170325093816_create_items.rb
      remove    app/models/item.rb
      invoke    test_unit
      remove      test/models/item_test.rb
      remove      test/fixtures/items.yml
      invoke  resource_route
       route    resources :items
      invoke  scaffold_controller
      remove    app/controllers/items_controller.rb
      invoke    test_unit
      remove      test/controllers/items_controller_test.rb
$ rails generate scaffold Item name:string price:integer
$ rails db:migrate
== 20170325094155 CreateItems: migrating ======================================
-- create_table(:items)
   -> 0.0045s
== 20170325094155 CreateItems: migrated (0.0058s) =============================

とりあえずできた。http://localhost:3000/itemsにアクセスすると商品一覧がみられる。

get /items 商品一覧取得
post /items 商品登録
get /items/1 商品詳細
put|patch /items/1 更新
delete /items/1 削除

postmanで登録してみる

url: (post)http://localhost:3000/items
body: item[name] => 納豆
      item[price] => 200

result

{
  "id": 1,
  "name": "納豆",
  "price": 200,
  "created_at": "2017-03-25T13:12:32.375Z",
  "updated_at": "2017-03-25T13:12:32.375Z"
}

クロスドメインアクセスOKにする場合、下記が必要。
APIファーストでバックエンドとフロントエンドを別々に開発する時にハマるクロスドメインアクセス
cyu/rack-cors

Gemfileに下記を追加。既に書いてあってコメントアウトされてるので、コメントを外す。

gem 'rack-cors'

bundle installする

$ bundle install

config/application.rbに下記のような感じで書く。

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', :headers => :any, :methods => [:get, :post, :options]
  end
end

ローカル環境だと、上記rack-corsの設定いらなかった。とりあえず、一覧、詳細、追加、修正、削除が全部できている。あとは、認証、認可、検索とか追加して本番環境で試したい。

参考:
Rails による API 専用アプリ

RailsでNoSQL使う – 参考サイト一覧

RailsでActiveRecordの代わりにMongoidを使う
Ruby On Rails で MongoDBを使ってみるよ
Railsを使ったMongoあれこれ。CRUDの基本操作で使い方を学ぼう!
Rails4 + Mongoidでデータ取得するあれこれ
mongodb/mongoid
Active Recordのその先へ ~RailsでMongoDBを使う~
CentOS6.2にMongoDBをインストールしてRailsで使う
Ruby での Cloud Datastore の使用
RubyでMySQL,MongoDB,Neo4jを共存させて用途に合わせて使い分ける。

RailsでAPIつくる – 参考サイト一覧

Rails5になってから、APIモードというのができたらしく余計なものをそぎ落としたAPIに特化したプロジェクトを作成できるらしい。

Rails5のAPIモードを超速で試す
Ruby on Rails 5のAPIモードと非APIモードのファイル差分
Rails5とAPIモードについての解説
Rails5 apiモード + JSONAPI ResourcesでAPIサーバを作る
Rails5 API + devise でユーザーの認証と追加機能を実装した API を作成する
webpack + React + Rails5 APIモードで環境構築
Rails 5.0.0.beta2 APIモードについて調べてみた
Rails5 APIではじめるSPA開発

Railsの人気gem

認証系

railsのマニュアルでも紹介されているのが下記2つ。
binarylogic/authlogic
plataformatec/devise

モデル系

モデルのコメントにテーブルの構造を表示してくれるらしい
ctran/annotate_models
検索機能
activerecord-hackery/ransack

View系

ページネーション
kaminari/kaminari

アップロード系

高機能で人気
carrierwaveuploader/carrierwavecarrierwaveuploader/carrierwave
シンプルで人気
thoughtbot/paperclip
carrierwaveの後継でより高機能らしー
refile/refile

管理画面系

activeadmin/activeadmin

ローカル開発系

ローカル開発時にメール送信をためせる
MailCatcher

その他

クローラー
chriskite/anemone
ABテスト
splitrb/split

その他たくさんあるな。cakephpとスターの量が違いすぎる。

参考;
Rails初心者におすすめなRubyGemsを7個厳選してみた
Ruby製サードパーティライブラリgemのトレンドを知るには「BestGems.org」がベスト
Railsアプリで実際に使用したオススメgem
Railsなプロジェクトで利用している便利なGem一覧
Railsやるなら知っておきたい便利Gem
Rubyを使うなら知っておきたいgemライブラリ10選

Railsの使い方(1)

チュートリアルやりながら、使い方まとめます。

railsコマンド

便利なコマンドが沢山ある。rails5になって変わったのも結構あるらしい。API用の軽量なやつをさくっと作れるとかもよさそう。

下記のように省略できる。

$ rails generate -> rails g
$ rails server -> rails s
$ rails console -> rails c
$ rails test -> rails t
$ bundle install -> bundle

元に戻す

rails destroyで大体何でも戻る

$ rails destroy model User
$ rails destroy controller StaticPage

マイグレーションは、rollback

$ rails db:rollback
$ rails db:migrate VERSION=0 #最初の状態に戻る

プロジェクトの作成

$ rails new hoge

Gemfileの編集

欲しいgem書く。groupをつくって環境を分ける。下記でインストールする。

$ bundle install

インストール対象外にしたいグループがある場合、下記のようにする。

$ bundle install --without production

Scaffold作成

rails generate scaffoldで作成できる。モデル名のあとにフィールドを書く。

$ rails generate scaffold User name:string email:string

マイグレーション

$ rails db:migrate

ルーティング

config/routes.rbを編集する。
resources :テーブル名、とするだけで一通りの規定のアクションにアクセスできるようになる。
root ‘controller#action’、とすればルート画面の設定できる。

Rails.application.routes.draw do
  resources :users
  root 'application#hello'
end

Model

下記のような感じで、テーブル同士の関係を書くことで勝手に紐づく。
models/user.rb

class User < ApplicationRecord
  has_many :microposts
end

バリデーションは下記のような感じ。メッセージはどこに書くのかな。
model/micropost.rb

class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140 }
end

コントローラ

rails generate controllerで作れる。コントローラ名のあとアクションを書ける。

$ rails generate controller StaticPage home help

テスト

コントローラのテストはこんな感じで書く。

require 'test_helper'

class StaticPageControllerTest < ActionDispatch::IntegrationTest
  test "should get home" do
    get static_page_home_url
    assert_response :success
  end

  test "should get help" do
    get static_page_help_url
    assert_response :success
  end

end

テスト実行

$ rails t

Railsの日本語ドキュメント

Ruby on Rails ガイド (5.0 対応)
電子書籍版もあってうれしい。
Ruby on Rails チュートリアル

チュートリアルからやる。

1-3 最初のアプリケーション

$ mkdir ruby
$ cd ruby
$ rails new hoge
$ cd hoge

フォルダ構成はここに書いてある。

railsサーバを立ち上げる

$ rails server

http://localhost:3000でアクセスできる。

1-4 Hello, world!

rubyは何でもシンプルだな。
アクションは、下記のように書く。

def hello
  render html: "hello, world!"
end

ルーターは、config/routes.rbで、下記のように書く。

root 'application#hello'

コントローラ#アクション

gitで管理する。

$ git init
$ git add -A
$ git commit -m 'first'

Herokuにデプロイしてみる
HerokuはPostgreSQLしか使えないので、Gemfileの本場用にpgを追加する。
まだ、他のgemfileを変更してないので、下記も追加した。

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen'
  gem 'spring'
  gem 'spring-watcher-listen'
end

group :production do
  gem 'pg'
end

bundle installする

$ bundle install --without production

Heroku CLIをインストールする。

$ heroku version
heroku-cli/5.7.10-3fe323c (windows-amd64) go1.7.5
$ heroku keys:add
$ heroku create
$ git push heroku master

2 Toyアプリケーション

$ git branch toy
$ git checkout toy

Railsのscaffoldは、rails generateスクリプトにscaffoldコマンドを渡すことで生成されます。 scaffoldコマンドの引数には、リソース名を単数形にしたもの (この場合はUser) を使用し、必要に応じてデータモデルの属性をオプションとしてパラメータに追加します

$ rails generate scaffold User name:string email:string

次はDBをマイグレートする。

$ rails db:migrate

何でもシンプルだなー。

@記号で始まる変数をRubyではインスタンス変数と呼び、Railsのコントローラ内で宣言したインスタンス変数はビューでも使えるようになります。

windows10でRuby on Railsを使う

ここからrubyのダウンロードする。Ruby 2.3.3 (x64)にした。インストールした。

$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]

エディタはRubyMine使う。

gemが使えない。

$ gem install rails
Please update your PATH to include build tools or download the DevKit
from ‘http://rubyinstaller.org/downloads’ and follow the instructions
at ‘http://github.com/oneclick/rubyinstaller/wiki/Development-Kit’

http://rubyinstaller.org/downloadsにあったからインストールした。

$ gem -v
2.5.2
$ gem update –system

できた。

$ gem -v
2.6.11

Ruby on Railsをインストール

$ gem install rails
$ rails -v
Rails 5.0.2

Railsのドキュメント見て勉強する。

webpack2でReactを使う

webpacke2でReactの開発環境を作る。

フォルダ・ファイルを作る

$ mkdir react1
$ cd react1
$ mkdir src
$ mkdir public
$ touch public/index.html
$ touch src/index.js
$ touch webpack.config.js
$ touch postcss.config.js

インストール

$ npm init -y
$ npm i -D webpack webpack-dev-server
$ npm i -D babel-loader babel-core babel-plugin-syntax-dynamic-import babel-preset-es2015 babel-preset-react
$ npm i -D extract-text-webpack-plugin
$ npm i -D style-loader css-loader postcss postcss-loader autoprefixer cssnano precss react-css-modules
$ npm i -D react react-dom

package.jsonは下記のようになった。

{
  "name": "react1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^6.7.7",
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.1",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "css-loader": "^0.27.3",
    "cssnano": "^3.10.0",
    "extract-text-webpack-plugin": "^2.1.0",
    "postcss": "^5.2.16",
    "postcss-loader": "^1.3.3",
    "precss": "^1.4.0",
    "react": "^15.4.2",
    "react-css-modules": "^4.1.0",
    "react-dom": "^15.4.2",
    "style-loader": "^0.16.0",
    "webpack": "^2.3.1",
    "webpack-dev-server": "^2.4.2"
  }
}

webpack.config.jsを作る

var path = require('path');
const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'public')
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'public'),
    port: 8080,
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: [
            'css-loader',
            'postcss-loader'
          ],
        })
      },
      {
        test: /\.js$/,
        use: [{
          loader: 'babel-loader',
          options: {
            presets: [
              ['es2015', {modules: false}],
              'react'
            ],
            plugins: ['syntax-dynamic-import']
          }
        }]
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('styles.css'),
    new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: {
        screw_ie8: false,
        keep_fnames: false
      },
      compress: {
        screw_ie8: true
      },
      comments: false
    })
  ]
};

postcss.config.jsを作る

module.exports = {
  plugins: [
    require('autoprefixer')({}),
    require('cssnano')({}),
    require('precss')({}),
    require('react-css-modules')({})
  ]
}

public/index.htmlを作る

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

src/index.jsを作る

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

webpackを実行する。実行後、public/bundle.jsが作成される。

$ webpack

webpack-dev-serverを実行する。実行後、http://localhost:8080にアクセスすると確認できる。

$ webpack-dev-server