- 追加された行はこの色です。
- 削除された行はこの色です。
- Railsメモ へ行く。
* Railsメモ [#ubc1fca1]
#setlinebreak(on);
- 関連
-- [[Ruby on Rails]]
-- [[Railsでユニットテストを行う]]
-- [[RailsでMongoDBを使用する]]
-- [[RailsでMongoDBを使用する為の環境設定メモ(Windows)]]
-- [[Railsのmongoidでユーザ認証]]
-- [[RailsでMondoid使用時のユニットテスト]]
-- [[ApacheとRailsをmod_proxyで連携する]]
-- [[Railsをthinで複数起動してApacheでロードバランス]]
-- [[websocket-railsインストール]]
#contents
** 独自定数を定義する [#f83f5d45]
#html(<div style="padding-left:20px;">)
発環境ごとに定数を管理できるconfig(旧:rails_config )を利用する。
Gemfileに追記
#mycode2(){{
gem 'config'
}}
インストール
#mycode2(){{
bundle install --path vendor/bundle
bundle exec rails g config:install
}}
定数の記述例) config/settings/development.yml
#mycode2(){{
test:
val1: "TEST_VAL1"
}}
利用例)
#mycode2(){{
Settings.test[:val1]
}}
#html(</div>)
&br;
** 数値編集 [#bf1d322c]
#html(<div style="padding-left:20px;">)
*** カンマ編集 [#he280aab]
#mycode2(){{
<%= number_with_delimiter(123456789) %> # => 123,456,789
}}
*** 表示桁数の指定 [#x6da8df4]
#mycode2(){{
<%= number_with_precision( 12.345, precision: 2 ) %> #=> 12.35
}}
*** 通貨 [#pb9a09bc]
#mycode2(){{
<%= number_to_currency( 1234.5 ) %> # => 1,235円 ※ロケール:ja の場合
}}
※ config/locales/ja.yml を編集する事で ¥1,235 のように表示する事も可能。
(number -> currency -> format 配下の format と unit )
#html(</div>)
&br;
** テキスト編集 [#y4ae9c3d]
#html(<div style="padding-left:20px;">)
*** 文字列の切り捨て [#ze9eee59]
#html(<div style="padding-left:10px;">)
#myhtml2(){{
<%= truncate("桁数や文言を指定して切り捨てます。オプションには : length、: separator、: omission が指定できます。", :length => 10) %>
<!-- 結果:「桁数や文言を指...」-->
<%= truncate("桁数や文言を指定して切り捨てます。オプションには : length、: separator、: omission が指定できます。", :length => 50, :separator => "。") %>
<!-- 結果:「桁数や文言を指定して切り捨てます...」-->
}}
オプション
|オプション|説明|h
|:length|切り捨てる桁数。(デフォルト:30)|
|:separator|切り捨てる箇所を表す文字列|
|:omission|切り捨て時に末尾に付与する文字列(デフォルト:...)|
#html(</div>)
*** ハイライト表示 [#c7d5905b]
#html(<div style="padding-left:10px;">)
#myhtml2(){{
<%= highlight('このヘルパー(highlight)は指定文字列をハイライト表示します', "highlight") %>
<!-- 結果:「このヘルパー(<mark>highlight</mark>)は指定文字列をハイライト表示します」-->
<%= highlight('このヘルパー(highlight)は指定文字列をハイライト表示します', "highlight", :highlighter => '<span style="color:#f00;">\1</span>') %>
<!-- 結果:「このヘルパー(<span style="color:#f00;">highlight</span>)は指定文字列をハイライト表示します」-->
}}
#html(</div>)
*** HTMLエスケープを抑制する [#l1e8777d]
#html(<div style="padding-left:10px;">)
#mycode2(){{
<%= "<a href='#test'>test link</a>" %> <!-- 結果:&lt;a href='#test'&gt;test link&lt;/a&gt; -->
<%= raw("<a href='#test'>test link</a>") %> <!-- 結果:<a href='#test'>test link</a> -->
<%= "<a href='#test'>test link</a>".to_s.html_safe %> <!-- 結果:<a href='#test'>test link</a> -->
}}
※ html_safe は nil の場合にエラーになるので、必ず to_s してから html_safe する方が良い。
#html(</div>)
#html(</div>)
&br;
** メッセージの国際化対応 [#pe301ed1]
#html(<div style="padding-left:20px;">)
*** config/application.rb を編集 [#bc725e50]
#mycode2(){{
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] # config/locales 配下のファイルを全て読み込む
config.i18n.default_locale = :ja
}}
*** config/locales 配下に定義ファイルを作成する [#mb3b0f8b]
例)
#html(<div style="border:1px solid #000;display:inline-block;padding:10px 20px 10px 20px;line-height:1.5;">)
#html(<span class="fa fa-folder-open"></span> config<br />)
#html( <span class="fa fa-folder-open"></span> locales<br />)
#html( <span class="fa fa-file-text-o"></span> en.yml<br />)
#html( <span class="fa fa-file-text-o"></span> ja.yml<br />)
#html( <span class="fa fa-folder-open"></span> messages<br />)
#html( <span class="fa fa-file-text-o"></span> en.yml<br />)
#html( <span class="fa fa-file-text-o"></span> ja.yml<br />)
#html(</div>)
*** 正しく定義されているか確認 [#r4e7d2e3]
#myterm2(){{
rails console
> YAML.load_file(Rails.root.join("config/locales/ja.yml"))
}}
#html(</div>)
&br;
** バリデータのメッセージを国際化対応する [#t1dc4782]
#html(<div style="padding-left:20px;">)
application.rb を編集([[application.rbの編集>#bc725e50]])したうえで、以下を実施。
*** 対象の言語のメッセージ定義ファイルを取得する [#vf54b7b6]
https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
*** 元(英語)の定義ファイルの内容が漏れ無く定義されているか確認 ※念のため [#f5499787]
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml
*** 取得したファイルを config/locales 配下に置く [#xf19fdf6]
#html(<div style="border:1px solid #000;display:inline-block;padding:10px 20px 10px 20px;line-height:1.5;">)
#html(<span class="fa fa-folder-open"></span> config<br />)
#html( <span class="fa fa-folder-open"></span> locales<br />)
#html( <span class="fa fa-file-text-o"></span> en.yml<br />)
#html( <span class="fa fa-file-text-o"></span><span style="color:#f00;font-weight:bold;"> ja.yml</span><br />)
#html(</div>)
#html(</div>)
&br;
** モデルの項目の日本語名を定義する [#geea34ae]
application.rb を編集([[application.rbの編集>#bc725e50]])したうえで、以下を実施。
#html(<div style="padding-left:20px;">)
例) config/locales/models/モデル名/ja.yml
#mycode2(){{
ja:
listing_book: "本の一覧"
editing_book: "本の編集"
activerecord:
#mongoid: # mongoid を使用している場合
models:
book: "本"
attributes:
book:
isbn: "ISBN"
title: "タイトル"
price: "値段"
}}
#html(</div>)
#html(<div style="padding-left:20px;">)
例) view/モデル名/index.html.erb
#mycode2(){{
<h1><%= t(:listing_book) %></h1>
・
・
<table>
<thead>
<tr>
<th><%= Book.human_attribute_name(:isbn) %></th>
<th><%= Book.human_attribute_name(:title) %></th>
<th><%= Book.human_attribute_name(:price) %></th>
<th colspan="3"></th>
</tr>
</thead>
・
・
}}
例) view/モデル名/edit.html.erb
#mycode2(){{
<h1><%= t(:editing_book) %></h1>
<%= render 'form' %>
<%= link_to 'Show', @book %> |
<%= link_to 'Back', books_path %>
}}
#html(</div>)
&br;
** ロケールを動的に切り替える(コントローラ等で) [#ef2ba0ad]
#html(<div style="padding-left:10px;">)
#myterm2(){{
I18n.locale = :ja
}}
#html(</div>)
&br;
** コントローラでチェック処理を行う [#p580b033]
#html(<div style="padding-left:20px;">)
#mycode2(){{
flash[:alert] = "XXしてください"
redirect_to :back
return
}}
または
#mycode2(){{
redirect_to :back, alert: 'XXしてください'
return
}}
#html(</div>)
&br;
** モデルのバリデーション定義 [#g35187aa]
#html(<div style="padding-left:20px;">)
*** 必須入力チェック(presence) [#q8bf1b3f]
#mycode2(){{
validates :name, :email, presence: true
}}
*** 空値チェック(absence) [#n19a3989]
#mycode2(){{
validates :login, absence: true
}}
*** 数値チェック(numericality) [#kb7e3a87]
#mycode2(){{
validates :price, numericality: true
validates :price, numericality: { only_integer: true } # 整数のみの場合
}}
※ greater_than、greater_than_or_equal_to、equal_to、less_than、less_than_or_equal_to 等のオプションも使用可能。
※ message にはプレースホルダとして %{count} が使用可能。
*** 正規表現チェック(format) [#z5647a33]
#mycode2(){{
validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/, message: "英文字で入力して下さい" }
}}
*** 長さチェック(length) [#zaebe04d]
#mycode2(){{
validates :name, length: { minimum: 2 }
validates :bio, length: { maximum: 500 }
validates :password, length: { in: 6..20 }
validates :registration_number, length: { is: 6 }
validates :bio, length: { maximum: 1000, too_long: "最大%{count}文字まで使用できます" }
}}
※エラーメッセージは :wrong_length、:too_long、:too_short オプションを指定してカスタマイズ可能。
*** 含有チェック(inclusion) [#b9618332]
#mycode2(){{
validates :size, inclusion: { in: %w(small medium large), message: "%{value} のサイズは無効です" }
}}
*** 一意チェック(uniqueness) [#d26c5baa]
#mycode2(){{
validates :name, uniqueness: true
}}
*** バリデーション専用の別クラスでチェック(validates_with) [#y85a8742]
#mycode2(){{
validates_with MyValidator
}}
※ 後述([[バリデーション専用クラスを使用する>#kaedd690]])
*** バリデーションオプション [#z272ddfc]
共通のオプションとして allow_nil、allow_blank、message、on が使用可能。
|オプション|説明|h
|allow_nil|値がnilの場合にバリデーションをスキップする|
|allow_blank|値がblank?の場合にバリデーションをスキップする(nil、空文字も含まれる)|
|message|カスタムエラーメッセージを指定する|
|on|バリデーション実行のタイミングを指定する|
#html(</div>)
&br;
** モデルのバリデーションをカスタマイズする [#r4c9d0ad]
#html(<div style="padding-left:20px;">)
*** カスタムバリデートを利用する [#g94e7c40]
#html(<div style="padding-left:10px;">)
#mycode2(){{
validate :my_validate
def my_validate
if name == "TEST"
errors.add(:name, "「TEST」は指定できません")
end
end
}}
#html(</div>)
*** バリデーション専用クラスを使用する [#kaedd690]
#html(<div style="padding-left:10px;">)
validates_with を使用して別のバリデーション専用クラスで定義した内容でチェックする事が可能。
#mycode2(){{
class MyValidator < ActiveModel::Validator
def validate(record)
if record.name == "TEST"
record.errors[:base] << "「TEST」は指定できません"
end
end
end
class Book < ActiveRecord::Base
validates_with MyValidator
end
}}
#html(</div>)
#html(</div>)
&br;
** モデルのチェック処理を呼び出す [#o8c3bda6]
#mycode2(){{
@user.valid?(:create)
}}
&br;
** SQLを直接実行する [#rc364266]
※http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html
#mycode2(){{
@books = ActiveRecord::Base.connection.select_all("select * from books")
}}
&br;
** coffeescript、scss を手動ビルドする [#rc8292fc]
#html(<div style="padding-left:20px;">)
#myterm2(){{
rake assets:precompile
}}
※app/assets 配下の scss, coffee がコンパイル/minifyされ、public/assets 配下に配置される
#html(</div>)
&br;
** 古いassetの削除(3世代分は残る?) [#rc8292fc]
#html(<div style="padding-left:20px;">)
#myterm2(){{
rake assets:clean
}}
#html(</div>)
&br;
** 古いassetの削除(完全) [#rc8292fc]
#html(<div style="padding-left:20px;">)
#myterm2(){{
rake assets:clobber
}}
#html(</div>)
&br;
** assets のパスを確認する [#x74c993a]
#myterm2(){{
rails console
> Rails.application.config.assets.paths
}}
&br;
** テンプレートをカスタマイズする [#fbd16602]
#html(<div style="padding-left:20px;">)
以下のコマンドでテンプレートのコピーをプロジェクト(lib/template)配下に作成する
#myterm2(){{
rake rails:templates:copy
}}
あとは作成されたテンプレートを編集するだけ。
#html(</div>)
** ジェネレータを作成する [#v0cfa6d5]
#html(<div style="padding-left:20px;">)
*** ジェネレータを使用してジェネレータを作成 [#p46879c1]
#myterm2(){{
rails generate generator modelyml
create lib/generators/modelyml
create lib/generators/modelyml/modelyml_generator.rb
create lib/generators/modelyml/USAGE
create lib/generators/modelyml/templates
invoke test_unit
create test/lib/generators/modelyml_generator_test.rb
}}
*** ジェネレータのソースを編集 [#j418178f]
例としてモデルの列名をYMLに定義するジェネレータを作成してみる
lib/generators/modelyml/modelyml_generator.rb
#mycode2(){{
class ModelymlGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)
# 定義したメソッドが上から順番に実行される
def makeyml
#@name ... 1つ目の引数
#@args ... 2つ目以降の引数
model = Module.const_get(@name.classify)
fields = model.fields
yml = ""
#yml += "ja:\n"
#yml += " " + "activerecord:\n" # orm が activerecord の場合
yml += " mongoid:\n" # orm が mongoid の場合
yml += " " + "models:\n"
yml += " " + model.name.downcase + ": \"" + model.name.downcase + "\"\n"
yml += " " + "attributes:\n"
yml += " " + model.name.downcase + ":\n"
fields.each_key do | key |
yml += " " + key + ": " + "\"" + key + "\"\n"
end
create_file("config/locales/models/" + model.name.downcase + "/en.yml", "en:\n" + yml)
create_file("config/locales/models/" + model.name.downcase + "/ja.yml", "ja:\n" + yml)
end
end
}}
*** 作成したジェネレータを実行 [#j4b19721]
#myterm2(){{
rails g modelyml book
<span class="green">create</span> config/locales/models/book/en.yml
<span class="green">create</span> config/locales/models/book/ja.yml
}}
#html(</div>)
&br;
** Scaffoldをカスタマイズする [#v0cfa6d5]
[[RailsでScaffoldの実行内容をカスタマイズする]]
&br;
** YMLを読み込む [#l3bfdf90]
#html(<div style="padding-left:20px;">)
#mycode2(){{
yml_data = YAML.load_file(Rails.root.join("config/locales/ja.yml"))
}}
#html(</div>)
&br;
** turbolinks使用時に各ページの初期処理を定義するには [#fd83e83d]
#html(<div style="padding-left:20px;">)
turbolinks を使用しているとページ遷移しても 全体は読み込まれない(body配下だけ書き換えられる)為、onloadイベントやjquery の ready イベント等は発生せず、page:load イベントが発火する。
・・が、page:load だけでは、どのページが読み込まれたかは判断できない為、ページ毎に初期化イベントをハンドリングする為に、少し手を加える。
views/layout/application.html.erb
#mycode2(){{
・
・
<body id="<%= controller_name %>-<%= action_name %>">
・
・
}}
assets/javascripts/_common.coffee ※jsのload順を調整する為に、共通系のjsは _(アンダーバー)で始まるファイル名にしておく等の考慮が必要
#mycode2(){{
pageInit = ->
id = $("body").attr("id");
$("#"+id).trigger("pageinit");
$(document).ready(pageInit)
$(document).on("page:load", pageInit)
}}
assets/javascripts/books.coffee
#mycode2(){{
###
初期表示(一覧)
###
pageInitIndex = (e) ->
console.info "books init pageinit!"
###
初期表示(詳細)
###
pageInitEdit = (e) ->
console.info "books edit pageinit!"
# ページ読込時(一覧)
$(document).on "pageinit", "#books-index", pageInitIndex
# ページ読込時(詳細)
$(document).on "pageinit", "#books-edit", pageInitEdit
}}
#html(</div>)
&br;
** ブレークポイントの設定 [#lde30d39]
#todo(pry-byebug2)
&br;