$ 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で囲われるから、それにスタイルつければ、エラーここだよ、というのが示せる。
次は、モデル(アクティブレコードと呼ぶらしい)のクエリ系のやつ覚えて、セッション、キャッシュとか確認して、認証のやり方確認して、セキュリティに関して確認したら大体何でもできそう。