Rails4 rake db:migrete実行前に戻す
Rails4 scopeでの並び順指定
scopeで並び順を昇順と降順に指定する方法のメモ。
例えば、scoreで並び順を指定する場合、昇順と降順は下記のように指定する。
# 昇順 scope :order_score, -> { order(:score) } # 降順 scope :order_score_desc, -> { order(score: :desc) }
参考:
Rails 4 default scope - Stack Overflow
Rails4 scopeでActiveRecordを簡潔に - ayaketanのプログラミング勉強日記
Rails4 アクション毎にレイアウトを変更する
アクション毎にレイアウトを変更しようとして、1度失敗したので、メモ。
下記の2つのレイアウトファイルを作成した。
app/views/layouts/basic.html.erb
app/views/layouts/custom.html.erb
indexにbasic.html.erbのレイアウト、showにcustom.html.erbのレイアウトを適用しようと、下記のように記載した。
class UsersController < ApplicationController layout 'basic', only: [:index] layout 'custom', only: [:show]
結果は、showにはcustom.html.erbのレイアウトが適用されたが、indexにはレイアウトが適用されなかった。
アクション毎にレイアウトを適用したい場合は、下記のようにrenderを使う。
def index @users = User.all render layout: 'basic' end def show render layout: 'custom' end
※アクションの最後にrenderを記載すること。
Rails4 1つのモデルに対して複数の参照がある場合のdependent destroy
ユーザーの組み合わせを定義したモデルをつくり、複数の参照を設定していた。
dependent destroyを設定しようとして躓いたので、メモ。
combinationモデルでは、user_idとpartner_idがuserモデルを参照しているものとする。
当初下記のように記載していた。
user.rb
has_many :combinations
combination.rb
belongs_to :user belongs_to :partner_user, class_name: 'User', foreign_key: "partner_id"
ここで、ユーザーが削除されたら組み合わせも削除しようと、user.rbを下記のように修正した。
has_many :combinations, dependent: :destroy
すると、ユーザーを削除した場合、user_idが一致するデータは削除されるが、partner_idが一致するデータは削除されなかった。
次のように修正するとうまくいった。
user.rb
has_many :combinations, dependent: :destroy has_many :partner_combinations, class_name: 'Combination', foreign_key: 'partner_id', dependent: :destroy
combination.rb
belongs_to :user belongs_to :partner_user, class_name: 'User', foreign_key: 'partner_id'
Rails4 date_selectにclassを指定する方法
date_selectにclassを指定したかったが、うまくいかなかった。
<%= f.date_select :deadline_at, order: [ :year, :month, :day ], use_month_numbers: true %>
オプションとHTMLのオプションを別の{}で囲むとうまくいった。
<%= f.date_select :deadline_at, {order: [ :year, :month, :day ], use_month_numbers: true}, {class: "form-control"} %>
参考
Rails の f.date_select とかで class を追加したい場合の件 - 牌語備忘録 - pygo
Rails4 レイアウトの継承
レイアウトを管理者と一般ユーザー用に分けたかった。
コントローラーを継承するのではなく、レイアウトで分ける方法を見つけたので、メモ。
app/views/layouts/application.html.erbに下記のように記載した。
<!DOCTYPE html> <html> <head> <title>SampleProject</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <button class="navbar-toggle" type="button" data-togle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <%= link_to "SampleProject", root_path, class: "navbar-brand" %> </div> <div class="navbar-collapse collapse"> <% unless yield(:navbar).empty? %> <%= yield(:navbar) %> <% end %> </div> </div> </div> <div id="content"> <%= content_for?(:content) ? yield(:content) : yield %> </div> </body> </html>
ポイントは、contentのこの部分。
contentが指定されていたら、そちらを使い、指定されていなければ、yieldでそれぞれのビューを読み込みます。
<div id="content"> <%= content_for?(:content) ? yield(:content) : yield %> </div>
app/views/layouts/admin.html.erbを作成し、下記のように記載。
contentにヘッダーを追加してみました。
<% content_for :content do %> <h1>システム管理者専用ページ</h1> <%= yield %> <% end %> <%= render template: "layouts/application" %>
app/controllers/admin/users_controller.rbで、レイアウトに先ほど作成したadmin.html.erbを指定する。
class Admin::UsersController < ApplicationController layout 'admin'
すると、この管理者用のユーザー画面には、applicationレイアウトで指定したナビバーと、adminレイアウトで指定した「システム管理者専用ページ」というヘッダーが表示され、ヘッダーの下にユーザー独自のレイアウトが設定される。
ちなみに、adminレイアウトを指定していない他のコントローラのビューは今まで通りに表示されます。
これは色々と応用できそうです。
Rails4 Chart.jsでレーダーチャートの目盛ラベルを変更する
chart.jsで描画したレーダーチャートの目盛ラベルを変更するのに苦戦したので、その方法をメモ。
コントローラで、表示したい目盛ラベルを変数に代入する。
デフォルトと同じ
@scale_label = "<%= value %>"
デフォルトの目盛ラベルにPを付加する場合
@scale_label = "<%= value %>P"
アルファベットに置き換える場合
@scale_label = "<%= value.replace('5','A').replace('4','B').replace('3','C').replace('2','D').replace('1','E') %>"
erbファイルでコントローラで設定した変数をscaleLabelにエスケープをオフにして設定する。
この時、<%= %>をダブルクォーテーションで囲むこと。
<!--レーダーチャートを描画する Canvas--> <canvas id="canvas" width="300px" height="300px"> </canvas> <%= javascript_include_tag "Chart" %> <script> $(function() { // レーダーチャートで表示するデータを用意 var radarChartData = { labels: ["スタミナ", "スピード", "テクニック", "パワー", "メンタル"], datasets: [ { fillColor: "rgba(151,187,205,0.5)", // 線で囲まれた部分の色 strokeColor: "rgba(151,187,205,1)", // 線の色 pointColor: "rgba(151,187,205,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: [3,4,5,2,3] } ] }; // Canvas にレーダーチャートを描画 var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var chart = new Chart(context); var rader = chart.Radar(radarChartData, { scaleOverride : true, // 目盛の設定を変更 scaleSteps : 5, // 目盛の数 scaleStepWidth : 1, // 目盛間隔 scaleStartValue : 0, // 目盛の最小値 scaleShowLabels : true, // 目盛ラベルの使用フラグ scaleLabel : "<%= @scale_label.html_safe %>", // 目盛ラベル animation: false // アニメーションの使用フラグ }); }); </script>